DUALテーブルを使用して、1から100までの数字のリストを取得するにはどうすればよいですか?
あなたの質問は理解するのが難しいですが、1
から100
、その後、これはトリックを行う必要があります:
Select Rownum r
From dual
Connect By Rownum <= 100
Oracle PL/SQLの別の興味深いソリューション:
SELECT LEVEL n
FROM DUAL
CONNECT BY LEVEL <= 100;
難しい方法でやってください。素晴らしいMODEL
句を使用します。
SELECT V
FROM DUAL
MODEL DIMENSION BY (0 R)
MEASURES (0 V)
RULES ITERATE (100) (
V[ITERATION_NUMBER] = ITERATION_NUMBER + 1
)
ORDER BY 1
Oracleのサブクエリファクトリ句「WITH」を使用すると、1〜100の数字を選択できます。
WITH t(n) AS (
SELECT 1 from dual
UNION ALL
SELECT n+1 FROM t WHERE n < 100
)
SELECT * FROM t;
整数を2つの整数の間にバインドする(つまり、1以外の値から開始する)場合は、次のようなものを使用できます。
with bnd as (select 4 lo, 9 hi from dual)
select (select lo from bnd) - 1 + level r
from dual
connect by level <= (select hi-lo from bnd);
それは与えます:
4
5
6
7
8
GROUP BY CUBE
を使用:
SELECT ROWNUM
FROM (SELECT 1 AS c FROM dual GROUP BY CUBE(1,1,1,1,1,1,1) ) sub
WHERE ROWNUM <=100;
数値テーブルを生成する楽しい方法を次に示します。 DUALテーブルは使用しませんが、DUALテーブルが消えてしまった場合、これはバックアップ計画になります。
DECLARE @TotalNumbers INT = 100;
DECLARE @From DATETIME = CONVERT(DATETIME, CONVERT(DATE, GETDATE())),
@To DATETIME = DATEADD(SECOND, @TotalNumbers - 1, CONVERT(DATETIME, CONVERT(DATE, GETDATE())));
WITH AlmostNumberTable (Hola)
AS (SELECT @From
UNION ALL
SELECT DATEADD(SECOND, 1, Hola)
FROM AlmostNumberTable
WHERE Hola< @To
)
SELECT [Number]
FROM
(
SELECT DATEPART(MINUTE, AlmostNumberTable.Hola) * 60 + DATEPART(SECOND, AlmostNumberTable.Hola) + 1 AS [Number]
FROM AlmostNumberTable
) AS NumberTable;
おそらくナンセンスですが、それは実用的なソリューションであり、書くのは楽しかったです。
Peterの例の変形であり、これを使用して0から99までのすべての数値を生成する方法を示します。
with digits as (
select mod(rownum,10) as num
from dual
connect by rownum <= 10
)
select a.num*10+b.num as num
from digits a
,digits b
order by num
;
このようなことは、バッチ識別子の割り当てを行い、まだ割り当てられていないアイテムを探すときに役立ちます。
たとえば、ビンゴチケットを販売している場合、100人のフロアスタッフのバッチを割り当てることができます(スポーツの募金にどのように使用したかを推測します)。バッチを販売すると、次のバッチが順番に渡されます。ただし、チケットを購入するユーザーは、バッチからチケットを購入することを選択できます。 「どのチケットが販売されたのか」という質問があります。
この場合、特定のバッチ内で返されたチケットの部分的でランダムなリストのみがあり、持っていないものを判別するためのすべての可能性の完全なリストが必要です。
with range as (
select mod(rownum,100) as num
from dual
connect by rownum <= 100
),
AllPossible as (
select a.num*100+b.num as TicketNum
from batches a
,range b
order by num
)
select TicketNum as TicketsSold
from AllPossible
where AllPossible.Ticket not in (select TicketNum from TicketsReturned)
;
キーワードの使用をお許しください。実際の例からいくつかの変数名を変更しました。
...なぜこのようなものが役立つのかを示すため
数値のテーブルを返すOracle関数を作成しました
CREATE OR REPLACE FUNCTION [schema].FN_TABLE_NUMBERS(
NUMINI INTEGER,
NUMFIN INTEGER,
EXPONENCIAL INTEGER DEFAULT 0
) RETURN TBL_NUMBERS
IS
NUMEROS TBL_NUMBERS;
INDICE NUMBER;
BEGIN
NUMEROS := TBL_NUMBERS();
FOR I IN (
WITH TABLA AS (SELECT NUMINI, NUMFIN FROM DUAL)
SELECT NUMINI NUM FROM TABLA UNION ALL
SELECT
(SELECT NUMINI FROM TABLA) + (LEVEL*TO_NUMBER('1E'||TO_CHAR(EXPONENCIAL))) NUM
FROM DUAL
CONNECT BY
(LEVEL*TO_NUMBER('1E'||TO_CHAR(EXPONENCIAL))) <= (SELECT NUMFIN-NUMINI FROM TABLA)
) LOOP
NUMEROS.EXTEND;
INDICE := NUMEROS.COUNT;
NUMEROS(INDICE):= i.NUM;
END LOOP;
RETURN NUMEROS;
EXCEPTION
WHEN NO_DATA_FOUND THEN
RETURN NUMEROS;
WHEN OTHERS THEN
RETURN NUMEROS;
END;
/
新しいデータ型を作成する必要があります:
CREATE OR REPLACE TYPE [schema]."TBL_NUMBERS" IS TABLE OF NUMBER;
/
使用法:
SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10))--integers difference: 1;2;.......;10
そして、指数表記法による数値間に小数が必要な場合:
SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10,-1));--with 0.1 difference: 1;1.1;1.2;.......;10
SELECT COLUMN_VALUE NUM FROM TABLE([schema].FN_TABLE_NUMBERS(1,10,-2));--with 0.01 difference: 1;1.01;1.02;.......;10