créer un nombre incrémentiel dans la requête SQL Oracle


13

comment créer un nombre incrémentiel dans une requête SQL Oracle sans créer de table? J'ai essayé d'utiliser la clause "avec", mais je n'ai pas réussi à obtenir le résultat attendu. J'utilise Oracle 10g

voici le code que j'essaye, il ne semble pas fonctionner:

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

le résultat attendu que je veux est:

2008
2009
2010
2011

Réponses:


14

Similaire à la réponse de Kerri, mais sans with(et inspiré par une réponse SO ):

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

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

Ou si votre objectif est d'obtenir l'année en cours les trois précédentes, sans coder en dur l'année de début:

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

1
Je pense que je vais choisir celui-ci pour mon code, c'est beaucoup plus simple que d'utiliser la clause With
50LV3R

16

Je pense que cela fonctionnera (basé sur cette page ( http://psoug.org/definition/LEVEL.htm ) comme point de départ):

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

Cela devrait retourner:

myYear
------
  2008
  2009
  2010
  2011

Ajustez 2008 et 4 pour obtenir des résultats différents.


5

Il semble que l'OP tentait de résoudre le problème à l'aide d'une sous-requête récursive. Cela ne fonctionnera pas dans 10g car cette fonctionnalité n'a pas été ajoutée avant 11.2, mais dans 11.2+, ce qui suit serait également une solution valide au problème.

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

La seule chose qui manquait à la requête du PO était (YEARS).


travaux légèrement modifiés dans MS SQL également WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
miracle173

@ miracle173 Intéressant, il suffit de supprimer le FROM dual.
Leigh Riffel

dualest une table spécifique à Oracle. D'autres bases de données comme MS SQL Sever, mysql, postgres autorisent des instructions comme select expression. mysql connaît aussi la double table
miracle173

4

Pourquoi ne pas simplement créer une séquence?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

ÉDITER:

Pour de petites plages de valeurs de séquence, vous pouvez utiliser quelque chose comme ceci:

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

Vous avez juste besoin d'une table avec un nombre suffisant de lignes.


3
On dirait beaucoup de surcharge pour quelque chose d'aussi trivial, et le DDL fera un commit implicite auquel on ne pourrait pas s'attendre. Et l'utilisateur émettant la requête peut ne pas être autorisé à créer une séquence.
Alex Poole

je suis d'accord avec Alex Poole, mais quand même, c'est une autre solution de contournement merci quand même
50LV3R

-1 pour les raisons indiquées par @AlexPoole. si vous réexécutez la requête sans recréer la séquence, vous obtenez un résultat différent.
miracle173

la requête qui utilise la séquence ne renvoie pas l'ensemble de nombres souhaité.
miracle173

-1

Voici un exemple d'ajout de plusieurs indicateurs et d'incrémentation en fonction de l'instruction 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' ;

- L'ensemble de résultats est ci-dessous

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
Pourquoi tout le casting entre chaînes et nombres? Je ne sais pas vraiment ce que cela ajoute aux réponses existantes car ce n'est pas quelque chose que l'OP semblait rechercher.
Alex Poole

-1

Augmentez seulement en un avec le rownum sélectionnez rownum + 100 dans l'ordre "table" de 1;

Ce résultat avec 101, 102 etc.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.