Utwórz liczbę przyrostową w zapytaniu SQL Oracle

13

Jak utworzyć liczbę przyrostową w zapytaniu SQL Oracle bez tworzenia tabeli? Próbowałem użyć klauzuli „z”, ale nie udało mi się uzyskać oczekiwanego rezultatu. Używam Oracle 10g

oto kod, który próbuję, wydaje się nie działać:

WITH
TABLE3 AS ( SELECT 2008 YEARS FROM dual WHERE 1=1
union all
select t3.YEARS+1 from TABLE3 t3
WHERE 1=1 AND t3.YEARS < 2011
)

select YEARS from TABLE3

oczekiwany wynik, który chcę:

2008
2009
2010
2011
50LV3R
źródło

Odpowiedzi:

14

Podobna do odpowiedzi Kerri, ale bez with(i inspirowana odpowiedzią SO ):

SELECT 2007 + LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4;

     YEARS
----------
      2008
      2009
      2010
      2011

Lub jeśli Twoim celem jest zdobycie bieżącego roku trzygo poprzedzającego go, bez twardego kodowania roku początkowego:

SELECT EXTRACT(YEAR FROM SYSDATE) + 1 - LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4
ORDER BY YEARS;
Alex Poole
źródło
1
myślę, że
wybiorę
16

Myślę, że to zadziała (na podstawie tej strony ( http://psoug.org/definition/LEVEL.htm ) jako punkt wyjścia):

WITH counter
AS ( SELECT LEVEL seq
       FROM DUAL
     CONNECT BY LEVEL <= 4 )
SELECT (2008 + seq - 1) myYear
  FROM counter
 ORDER BY 1
;

To powinno zwrócić:

myYear
------
  2008
  2009
  2010
  2011

Dostosuj 2008 i 4, aby uzyskać różne wyniki.

Kerri Shotts
źródło
5

Wygląda na to, że OP próbował rozwiązać problem za pomocą rekurencyjnego podkwerendy. To nie zadziała w 10g, ponieważ ta funkcjonalność została dodana dopiero w 11.2, ale w 11.2+ następujące rozwiązanie byłoby również poprawnym rozwiązaniem problemu.

WITH T3(Years) AS (
   SELECT 2008 Years FROM dual
   UNION ALL
   SELECT Years + 1 FROM T3 WHERE Years < 2011
   )
SELECT * FROM T3;

Jedyne, czego brakuje w zapytaniu PO, to (YEARS).

Leigh Riffel
źródło
nieco zmodyfikowane działa również w MS SQL WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
miracle173
@ miracle173 Ciekawe, wystarczy usunąć FROM dual.
Leigh Riffel,
dualjest tabelą specyficzną dla wyroczni. Inne bazy danych, takie jak MS SQL Sever, mysql, postgres pozwalają na instrukcje takie jak select expression. mysql zna również podwójny stół
cud 173
4

Dlaczego nie stworzyć sekwencji?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

EDYTOWAĆ:

W przypadku małych zakresów wartości sekwencji można użyć czegoś takiego:

select ROWNUM + 10   # start value
from ALL_OBJECTS 
where ROWNUM <= 5 ;  # count of values 

Potrzebujesz tylko tabeli z wystarczającą liczbą wierszy.

bernd_k
źródło
3
Wydaje się, że jest to narzut związany z czymś tak trywialnym, a DDL wykona ukryte zatwierdzenie, którego nie można oczekiwać. Użytkownik wydający zapytanie może nie mieć uprawnień do utworzenia sekwencji.
Alex Poole,
zgadzam się z Alexem Poole, ale mimo to jest to kolejne obejście dzięki
50LV3R
-1 z podanych powodów @AlexPoole. jeśli ponownie wykonasz zapytanie bez odtworzenia sekwencji, otrzymasz inny wynik.
miracle173
zapytanie korzystające z sekwencji nie zwraca żądanego zestawu liczb.
miracle173
-1

Oto przykład dodawania wielu flag i zwiększania wartości na podstawie instrukcji case.

WITH T3(FLAG1,FLAG2,FLAG3,tt,OTHER_DATA)  
AS (    
SELECT '0' FLAG1, '0' FLAG2, '0' FLAG3 , current_timestamp  tt , 'dummy'  OTHER_DATA 
FROM dual 
UNION ALL  
SELECT case when cast( FLAG2 as int) > 5 then
cast ((cast(FLAG1 as int) + 1) as varchar2(30)) else  FLAG1 end FLAG1,
cast((cast(FLAG2 as int) + 1) as varchar2(30)) FLAG2  ,case when (
(FLAG2 ='3') or (FLAG2 = '4')) then cast ((cast(  FLAG3 as int) + 1)
as varchar2(30)) else FLAG3 end FLAG3  ,current_timestamp  tt ,
'ACTUAL' OTHER_DATA FROM T3 WHERE FLAG2 < 10   
)
SELECT * FROM T3
WHERE OTHER_DATA != 'dummy' ;

- Zestaw wyników znajduje się poniżej

Flag1   Flag2   Flag3   TT                                              OTHER_DATA
0       1       0       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
0       2       0       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
0       3       0       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
0       4       1       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
0       5       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
0       6       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
1       7       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
2       8       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
3       9       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL
4      10       2       21-DEC-15 08.31.05.229502000 PM ASIA/CALCUTTA   ACTUAL   
Suyaraj Mariappan
źródło
2
Dlaczego wszystkie odlewania między ciągami i liczbami? Nie jestem do końca pewien, co to dodaje do istniejących odpowiedzi, ponieważ nie wydawało się, że OP tego szuka.
Alex Poole,
-1

Zwiększ tylko w jednym z rownum wybierz rownum + 100 z „tabeli” o 1;

Ten wynik z 101, 102 itd.

L.Luca
źródło