criar número incremental na consulta oracle sql

13

como criar um número incremental na consulta oracle sql sem criar nenhuma tabela? Eu tentei usar a cláusula "with", mas não obtive o resultado esperado. Estou usando o oracle 10g

aqui está o código que eu tento, parece não funcionar:

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

resultado esperado que eu quero é:

2008
2009
2010
2011
50LV3R
fonte

Respostas:

14

Semelhante à resposta de Kerri, mas sem a with(e inspirada por uma resposta de SO ):

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

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

Ou se seu objetivo é obter o ano atual nos três anteriores, sem codificar o ano inicial:

SELECT EXTRACT(YEAR FROM SYSDATE) + 1 - LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4
ORDER BY YEARS;
Alex Poole
fonte
1
eu acho que vai escolher um presente para o meu código, o seu muito mais simples do que usar a cláusula
50LV3R
16

Eu acho que isso funcionará (com base nesta página ( http://psoug.org/definition/LEVEL.htm ) como ponto de partida):

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

Isso deve retornar:

myYear
------
  2008
  2009
  2010
  2011

Ajuste 2008 e 4 para obter resultados diferentes.

Kerri Shotts
fonte
5

Parece que o OP estava tentando resolver o problema usando uma subconsulta recursiva. Isso não funcionará em 10g porque essa funcionalidade não foi adicionada até 11.2, mas em 11.2 ou superior, o seguinte também seria uma solução válida para o problema.

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

A única coisa que faltava na consulta do OP era (YEARS).

Leigh Riffel
fonte
obras ligeiramente modificado em MS SQL bem WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
miracle173
@ miracle173 Interessante, basta remover o FROM dual.
Leigh Riffel
dualé uma tabela específica do oracle. Outros bancos de dados como MS SQL Sever, mysql, postgres permitem declarações como select expression. mysql faz saber a uma dupla mesa também
miracle173
4

Por que não apenas criar uma sequência?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

EDITAR:

Para pequenos intervalos de valores de sequência, você pode usar algo como isto:

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

Você só precisa de uma tabela com um número suficiente de linhas.

bernd_k
fonte
3
Parece muita sobrecarga para algo tão trivial, e o DDL fará um commit implícito que pode não ser esperado. E o usuário que está emitindo a consulta pode não ter permissão para criar uma sequência.
Alex Poole
eu concordo com o Alex Poole, mas ainda assim, é outra solução obrigado de qualquer maneira
50LV3R
-1 pelas razões indicadas pelo @AlexPoole. se você reexecute a consulta sem recriar a sequência, obtém um resultado diferente.
miracle173
a consulta que usa a sequência não retorna o conjunto de números desejado.
precisa saber é o seguinte
-1

Aqui está um exemplo de adicionar vários sinalizadores e incrementá-los com base na instrução de 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' ;

- O conjunto de resultados está abaixo

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
fonte
2
Por que todo o casting entre strings e números? Não tenho certeza do que isso acrescenta às respostas existentes, pois não é algo que o OP pareça estar procurando.
Alex Poole
-1

Aumente apenas um com o rownum e selecione rownum + 100 da ordem "tabela" em 1;

Esse resultado com 101, 102 etc.

L.Luca
fonte