creare un numero incrementale nella query oracle sql


13

come creare un numero incrementale nella query oracle sql senza creare alcuna tabella? Ho provato a utilizzare la clausola "with", ma non sono riuscito a ottenere il risultato previsto. Sto usando Oracle 10g

ecco il codice che provo, sembra non funzionare:

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

il risultato atteso che desidero è:

2008
2009
2010
2011

Risposte:


14

Simile alla risposta di Kerri, ma senza il with(e ispirato a una risposta SO ):

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

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

O se il tuo obiettivo è quello di ottenere l'anno in corso i tre precedenti, senza codificare l'anno di inizio:

SELECT EXTRACT(YEAR FROM SYSDATE) + 1 - LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4
ORDER BY YEARS;

1
penso che sceglierò questo per il mio codice, è molto più semplice dell'uso della clausola With
50LV3R

16

Io penso che questo lavoro volontà (sulla base di questa pagina ( http://psoug.org/definition/LEVEL.htm ) come punto di partenza):

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

Questo dovrebbe restituire:

myYear
------
  2008
  2009
  2010
  2011

Modifica 2008 e 4 per ottenere risultati diversi.


5

Sembra che l'OP stesse tentando di risolvere il problema utilizzando una sottoquery ricorsiva. Questo non funzionerà in 10g perché quella funzionalità non è stata aggiunta fino alla 11.2, ma in 11.2+ anche questa sarebbe una valida soluzione al problema.

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

L'unica cosa che mancava nella query del PO era (YEARS).


funziona leggermente modificato anche in MS SQL WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
miracle173

@ miracle173 Interessante, basta rimuovere il FROM dual.
Leigh Riffel,

dualè una tabella specifica dell'oracolo. Altri database come MS SQL Sever, mysql, postgres consentono dichiarazioni come select expression. mysql conosce anche il doppio tavolo
miracle173

4

Perché non creare semplicemente una sequenza?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

MODIFICARE:

Per piccoli intervalli di valori di sequenza puoi usare qualcosa del genere:

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

Hai solo bisogno di una tabella con un numero sufficiente di righe.


3
Sembra un sacco di spese generali per qualcosa di così banale, e il DDL farà un impegno implicito che non ci si potrebbe aspettare. E l'utente che emette la query potrebbe non essere autorizzato a creare una sequenza.
Alex Poole,

sono d'accordo con Alex Poole, ma comunque è un'altra soluzione grazie comunque
50LV3R

-1 per i motivi indicati da @AlexPoole. se riesegui la query senza ricreare la sequenza otterrai un risultato diverso.
miracle173,

la query che utilizza la sequenza non restituisce il set di numeri desiderato.
miracle173,

-1

Ecco un esempio di aggiunta di più flag e di incremento di quello basato sull'istruzione 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' ;

- Il set di risultati è sotto

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   

2
Perché tutto il casting tra stringhe e numeri? Non sono del tutto sicuro di ciò che si aggiunge alle risposte esistenti in quanto non è qualcosa che l'OP sembrava cercare.
Alex Poole,

-1

Aumenta solo in uno con il rownum seleziona rownum + 100 dall'ordine "tabella" di 1;

Quel risultato con 101, 102 ecc.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.