web-dev-qa-db-ja.com

ORACLE SQL:2つの数値間のすべての整数を取得する

OracleのSQLで2つの数値の間に含まれる数値(整数)を選択する方法はありますか。 PL/SQLプロシージャまたは関数を作成したくありません。

たとえば、3〜10の数値を取得する必要があります。結果は、3、4、5、6、7、8、9、10の値になります。

THX。

21
George

OracleのDUALテーブルでのこのトリックも機能します。

SQL> select n from
  2  ( select rownum n from dual connect by level <= 10)
  3  where n >= 3;

         N
----------
         3
         4
         5
         6
         7
         8
         9
        10
52
Tony Andrews

first新しいデータベースを作成するときに行うことは、いくつかの基本的なテーブルを作成してデータを設定することです。

1つは-NからNまでのすべての整数のリスト、もう1つは過去5年から10年後の日付のリスト(スケジュールされたジョブは必要に応じてこれらを作成し続けることができます)、最後はリストです一日中すべての時間の。たとえば、inetgers:

create table numbers (n integer primary key);
insert into numbers values (0);
insert into numbers select n+1 from numbers; commit;
insert into numbers select n+2 from numbers; commit;
insert into numbers select n+4 from numbers; commit;
insert into numbers select n+8 from numbers; commit;
insert into numbers select n+16 from numbers; commit;
insert into numbers select n+32 from numbers; commit;
insert into numbers select n+64 from numbers; commit;
insert into numbers select n+128 from numbers; commit;
insert into numbers select n+256 from numbers; commit;
insert into numbers select n+512 from numbers; commit;
insert into numbers select n+1024 from numbers; commit;
insert into numbers select n+2048 from numbers; commit;
insert into numbers select n+4096 from numbers; commit;
insert into numbers select n+8192 from numbers; commit;
insert into numbers select -n from numbers where n > 0; commit;

これは、自動トランザクション開始を備えたDB2/z用であり、ネイキッドコミットを持っているように見えます。

はい、それは(最小限の)スペースを占有しますが、それらのテーブルから値を選択するだけで、クエリをmuch作成しやすくします。また、かなり移植性がありますany SQLベースのDBMS。

その場合、特定のクエリは単純になります。

select n from numbers where n >=3 and n <= 10;

時間の数値と日付範囲は、私たちが取り組んでいるレポートアプリケーションの種類に非常に役立ちます。これにより、実際のデータがない時間帯(または日付)のゼロエントリを作成できるため、代わりに(月の2日にデータがない場合):

Date       | Quantity
-----------+---------
2009-01-01 |        7
2009-01-03 |       27
2009-01-04 |        6

代わりに以下を取得できます。

Date       | Quantity
-----------+---------
2009-01-01 |        7
2009-01-02 |        0
2009-01-03 |       27
2009-01-04 |        6
5
paxdiablo

これにはMODEL句を使用できます。

SELECT c1 from dual
  MODEL DIMENSION BY (1 as rn)  MEASURES (1 as c1)
  RULES ITERATE (7)
  (c1[ITERATION_NUMBER]=ITERATION_NUMBER+7)
4
Gary Myers
SQL> var N_BEGIN number
SQL> var N_END number
SQL> exec :N_BEGIN := 3; :N_END := 10

PL/SQL procedure successfully completed.

SQL>  select :N_BEGIN + level - 1 n
  2     from dual
  3  connect by level <= :N_END - :N_BEGIN + 1
  4  /

         N
----------
         3
         4
         5
         6
         7
         8
         9
        10

8 rows selected.

これはトニーと同じトリックを使用しています。 SQL * Plus 9を使用している場合、Tonyが示したように、このクエリをインラインビューにする必要があることに注意してください。 SQL * Plus 10以降では、上記で十分です。

よろしく、ロブ。

4
Rob van Wijk

この1行のクエリが役立ちます。

select level lvl from dual where level<:upperbound and 

                              level >:lowerbound connect by level<:limt

あなたの場合:

select level lvl from dual where level<10 and level >3 connect by level<11

不明な点がある場合はお知らせください。

3
Thiyagu ATR

またはBetweenを使用できます

Select Column1 from dummy_table where Column2 Between 3 and 10
1
Amit

範囲から数値を生成する1つの方法は、XMLTABLE('start to end')を使用することです。

SELECT column_value
FROM XMLTABLE('3 to 10');

DBFiddle Demo

1
Lukasz Szozda

これは遅い追加です。しかし、ソリューションはよりエレガントで使いやすいようです。

これは、一度インストールする必要があるパイプライン関数を使用します。

CREATE TYPE number_row_type AS OBJECT 
(
  num NUMBER
);

CREATE TYPE number_set_type AS TABLE OF number_row_type;

CREATE OR REPLACE FUNCTION number_range(p_start IN PLS_INTEGER, p_end IN PLS_INTEGER)
    RETURN number_set_type
    PIPELINED
IS
    out_rec number_row_type := number_row_type(NULL);

BEGIN
  FOR i IN p_start .. p_end LOOP
    out_rec.num := i;
    pipe row(out_rec);
  END LOOP;

END number_range;
/

その後、次のように使用できます。

select * from table(number_range(1, 10));

NUM
---
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10

ソリューションはOracle固有です。

1
Codo

ゲイリー、彼が説明した結果を示すために、モデルクエリは次のようになります。

デュアルモデルの寸法からc1を選択(1はrnとして)
MEASURES(1 as c1)ルールITERATE(8)(c1 [ITERATION_NUMBER] = ITERATION_NUMBER + 3)ORDER BY rn

;)

私は常に使用します:

SELECT(LEVEL-1)+ 3結果としてDual CONNECT BY Level <= 8から

3は開始番号、8は「反復」の数です。

1
anthian

私はSQL Serverでこれを行うためにテーブル値関数を実行しましたが、誰かが興味を持っていれば、これは完璧に機能します。

CREATE FUNCTION [dbo].[NumbersBetween]
(
    @StartN int,
    @EndN int
)
RETURNS 
@NumberList table
(
    Number int
)

AS

BEGIN

WHILE @StartN <= @EndN
    BEGIN
    insert into @NumberList
    VALUES (@StartN)
    set @StartN = @StartN + 1
    END

Return

END
GO

クエリを実行する場合: "select * from dbo.NumbersBetween(1,5)"(もちろん引用符なし)結果は次のようになります

Number
-------
1
2
3
4
5
0
Gaspa79

カンマの文字列と数値の「-」で区切られたリストを同等の拡張された数値のリストに変換する便利なクエリを共有したいと思います。

「1,2,3,50-60」をに変換する例

 1 
 2 
 3 
 50 
 51 
 ... 
 60 
select distinct * from (SELECT (LEVEL - 1) + mini as result FROM (select REGEXP_SUBSTR (value, '[^-]+', 1, 1)mini ,nvl(REGEXP_SUBSTR (value, '[^-]+', 1, 2),0) maxi from (select REGEXP_SUBSTR (value, '[^,]+', 1, level) as value from (select '1,2,3,50-60' value from dual) connect by level <= length(regexp_replace(value,'[^,]*'))+1)) CONNECT BY Level <= (maxi-mini+1)) order by 1 asc;

これをビューとして使用して、「1,2,3,50-60」文字列をパラメータ化できます

0
antoniolvsa
create table numbers (value number);

declare
    x number;
begin
    for x in 7 .. 25
    loop
        insert into numbers values (x);
    end loop;
end;
/
0
diaphol