Oracle SQLクエリで増分番号を作成する


13

テーブルを作成せずにOracle SQLクエリで増分番号を作成する方法は?「with」句を使用してみましたが、期待した結果が得られませんでした。Oracle 10gを使用しています

ここに私が試したコードがありますが、動作していないようです:

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

Kerriの答えに似ていますが、なしでwith(そしてSOの答えに触発されました):

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

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

または、開始年をハードコーディングせずに、現在の年をその3つ前に取得することを目的としている場合:

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

OPが再帰サブクエリを使用して問題を解決しようとしたようです。この機能は11.2まで追加されなかったため、これは10gでは機能しませんが、11.2以上では、次の問題も有効な解決策となります。

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

OPのクエリから欠落している唯一のものはでした(YEARS)


MS SQLでも若干変更された作品 WITH T3(Years) AS ( SELECT 2008 Years UNION ALL SELECT Years + 1 FROM T3 WHERE Years < 2011 ) SELECT * FROM T3;
-miracle173

@ miracle173興味深いことに、単に削除しFROM dualます。
リーリッフェル

dualOracle固有のテーブルです。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
なぜ文字列と数字の間のすべてのキャストですか?OPが探しているようには見えなかったので、これが既存の回答に何を追加するのか完全にはわかりません。
アレックスプール

-1

rownum select rownum + 100で1つだけ「table」の順序から1ずつ増加します。

その結果は101、102などです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.