создать инкрементный номер в SQL-запросе Oracle

13

Как создать инкрементное число в Oracle SQL запрос без создания какой-либо таблицы? Я пытался использовать предложение «с», но мне не удалось получить ожидаемый результат. Я использую оракул 10г

Вот код, который я пытаюсь, кажется, не работает:

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

ожидаемый результат, который я хочу, это:

2008
2009
2010
2011
50LV3R
источник

Ответы:

14

Аналогично ответу Керри, но без with(и вдохновлен SO ответом ):

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

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

Или, если ваша цель состоит в том, чтобы получить текущий год тремя предшествующими ему, без жесткого кодирования начального года:

SELECT EXTRACT(YEAR FROM SYSDATE) + 1 - LEVEL AS YEARS
FROM DUAL
CONNECT BY LEVEL <= 4
ORDER BY YEARS;
Алекс Пул
источник
1
я думаю, что выберу это для своего кода, это гораздо проще, чем с помощью предложения With
50LV3R
16

Я думаю, что это будет работать (основываясь на этой странице ( http://psoug.org/definition/LEVEL.htm ) в качестве отправной точки):

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

Это должно вернуть:

myYear
------
  2008
  2009
  2010
  2011

Настройте 2008 и 4, чтобы получить разные результаты.

Керри Шоттс
источник
5

Похоже, что ОП пытался решить проблему с помощью рекурсивного подзапроса. Это не будет работать в 10g, потому что эта функциональность не была добавлена ​​до 11.2, но в 11.2+ следующее также будет правильным решением проблемы.

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

Единственное, чего не хватало в запросе ОП, было (YEARS).

Ли Риффель
источник
Слегка видоизмененный работает и в MS SQL WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
чудо173
@ miracle173 Интересно, просто удали FROM dual.
Ли Риффель
dualэто таблица конкретного оракула. Другие базы данных, такие как MS SQL Sever, mysql, postgres, допускают такие операторы, как select expression. MySQL тоже знает двойную таблицу
miracle173
4

Почему бы просто не создать последовательность?

CREATE SEQUENCE TEMP_YEAR_sEQUENCE START WITH 2008;

SELECT TEMP_YEAR_sEQUENCE.NEXTVAL FROM DUAL; 

....

DROP SEQUENCE TEMP_YEAR_SEQUENCE;

РЕДАКТИРОВАТЬ:

Для небольших диапазонов значений последовательности вы можете использовать что-то вроде этого:

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

Вам просто нужна таблица с достаточным количеством строк.

bernd_k
источник
3
Кажется, что это слишком много для чего-то такого тривиального, и DDL сделает неявную фиксацию, которая может и не ожидаться. И пользователь, отправляющий запрос, может не иметь разрешения на создание последовательности.
Алекс Пул
Я согласен с Алексом Пулом, но, тем не менее, это еще один обходной путь, в любом случае
50LV3R
-1 по причинам, указанным @AlexPoole. если вы повторно выполните запрос без воссоздания последовательности, вы получите другой результат.
чудо173
запрос, который использует последовательность, не возвращает желаемый набор чисел.
чудо173
-1

Вот пример добавления нескольких флагов и увеличения их на основе оператора 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' ;

- Результат ниже

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
Почему все преобразования между строками и числами? Не совсем уверен, что это добавляет к существующим ответам, так как это не то, что казалось, что ОП ищет.
Алекс Пул
-1

Увеличивайте только в одном с rownum, выберите rownum + 100 из «столового» порядка на 1;

Этот результат с 101, 102 и т. Д.

L.Luca
источник