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.