crear un número incremental en la consulta SQL Oracle

13

¿Cómo crear un número incremental en la consulta SQL Oracle sin crear ninguna tabla? Intenté usar la cláusula "con", pero no pude obtener el resultado esperado. Estoy usando Oracle 10g

Aquí está el código que intento, parece que no funciona:

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

El resultado esperado que quiero es:

2008
2009
2010
2011
50LV3R
fuente

Respuestas:

14

Similar a la respuesta de Kerri, pero sin el with(e inspirado en una respuesta SO ):

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

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

O si su objetivo es obtener el año actual los tres anteriores, sin codificar el año de inicio:

SELECT EXTRACT(YEAR FROM SYSDATE) + 1 - LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4
ORDER BY YEARS;
Alex Poole
fuente
1
creo que elegiré este para mi código, es mucho más simple que usar la cláusula With
50LV3R
16

Creo que esto funcionará (basado en esta página ( http://psoug.org/definition/LEVEL.htm ) como punto de partida):

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

Esto debería devolver:

myYear
------
  2008
  2009
  2010
  2011

Ajuste 2008 y 4 para obtener resultados diferentes.

Kerri Shotts
fuente
5

Parece que el OP estaba intentando resolver el problema utilizando una subconsulta recursiva. Esto no funcionará en 10g porque esa funcionalidad no se agregó hasta 11.2, pero en 11.2+ lo siguiente también sería una solución válida para el problema.

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

Lo único que faltaba en la consulta del OP era (YEARS).

Leigh Riffel
fuente
obras ligeramente modificadas en MS SQL también WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
milagro173
@ miracle173 Interesante, simplemente elimine el FROM dual.
Leigh Riffel
duales una tabla específica de oráculo. Otras bases de datos como MS SQL Sever, mysql, postgres permiten declaraciones como select expression. mysql también conoce la tabla dual
miracle173
4

¿Por qué no simplemente crear una secuencia?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

EDITAR:

Para rangos pequeños de valores de secuencia puede usar algo como esto:

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

Solo necesita una tabla con un número suficiente de filas.

bernd_k
fuente
3
Parece una gran sobrecarga para algo tan trivial, y el DDL hará una confirmación implícita que podría no esperarse. Y el usuario que emite la consulta podría no tener permiso para crear una secuencia.
Alex Poole
Estoy de acuerdo con Alex Poole, pero aún así, es otra solución, gracias de todos modos
50LV3R
-1 por los motivos @AlexPoole declaró. Si vuelve a ejecutar la consulta sin volver a crear la secuencia, obtendrá un resultado diferente.
milagro173
la consulta que usa la secuencia no devuelve el conjunto de números deseado.
milagro173
-1

Aquí hay un ejemplo de agregar varias marcas e incrementarlas en función de la declaración del caso.

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' ;

- El conjunto de resultados está debajo

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
fuente
2
¿Por qué todo el casting entre cadenas y números? No estoy completamente seguro de lo que esto agrega a las respuestas existentes, ya que no es algo que el OP parecía estar buscando.
Alex Poole
-1

Aumente solo en uno con el rownum select rownum + 100 del orden de "tabla" en 1;

Ese resultado con 101, 102 etc.

L.Luca
fuente