создать инкрементный номер в 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

Ответы:


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 

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


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 и т. Д.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.