2016-12-01 20 views
0

私は手元にある値のリストを持っています。値が下がっているテーブルの範囲を調べたいと思います。値(475747003, 476367781, 454313069, 454545398, etc.,)値のリストの範囲を見つけます - sqlの 'between'演算子

一覧 - 値の1000のDBテーブルの

範囲のようになります。私の出力はつまり、私はすべての1000のためのStart_RangeEnd_Rangeを知りたい、以下のようにする必要があり

Start_Range  End_Range 
-------------------------- 
475747000  475747999 
476367781  476367782 
454313059  454313069 

値の私は 'Between'演算子を使用しようとしましたが、 '値のリスト'のためにそれを使用する方法がわかりませんでしたか?

Start_Range  End_Range 
-------------------------- 
475747000  475747999 
476367781  476367782 
454313059  454313069 

だから基本的には、SQLスクリプト以下

select * from TABLE 
where (475747003, 476367781, 454313069, 454545398) between start_range and end_range; 

ORA-01796、エラーがスローされます。この演算子はリスト 01796. 00000で使用することはできません - 「この演算子はリストを使用することはできません"

だから私は別の方法を探したい。

+0

で何かをMAX()とMIN()またはTOP 1 ORDER BYとTOP 1 ORDER BY DESCの間で、値がBETWEEN xとyが頭に浮かびます。 –

+0

どのDBMSを使用していますか? –

+2

私はまた、2つの例の違いを表示していません –

答えて

0

「通常の」クエリでは実行できません(最も近いのは値リストの場合はIN演算子ですが、等値以外はテストできません)。

select myValues.myValue, r.Start_Range, r.End_Range 
from (
    select 11111 as MyValue from dual union all 
    select 22222 as MyValue from dual union all 
    select 33333 as MyValue from dual union all 
    ... // all of the values you want to search for 
    select 99999 as MyValue from dual 
) as myValues 
inner join RangesTable r on myValues.myValue between r.Start_Range and r.End_Range 

同じことあなたは一時テーブルを使用する場合:このように、一時テーブル、あるいは「仮想」テーブルを使用してについて何

。 dbはに設定して扱うことができるものに値を取得してから、範囲に結合するだけです。

+0

もちろんこれは "通常の"クエリで行うことができます。 'IN'だけが利用可能な演算子ではありません。 'EXISTS'は平等以外の条件で使うことができます(この場合完全にうまくいくでしょう)。 – mathguy

+0

「値のリスト」をセットベースの操作のセットに変えなければならないと言っているだけです。それ以外は、確かに、それは正常です。 – SlimsGhost

+0

ああ、OK - 「テスト値がすでにテーブルに入っていても、あなたは「IN」しか使えず、それはレンジのテストに使うことができません」と思った。もしあなたが意図したことがリストをテーブルに変換していたら、それはもう一つの問題です(テーブル(sys.odcinumberlist(..))を使って説明した方法もかなり標準です)。 – mathguy

0

以下のクエリでは、CTEの範囲テーブルを模倣しています(ソリューションの一部ではなく、実際の問題ではメインクエリのテーブルを参照するだけです)。 「飛行中に構築された数字のテーブルとして」範囲と照合されます。以下のクエリに一致する範囲を表示する必要があるだけだと言いました。個々の値と一致する範囲を示します(値が範囲内にない場合はNULLを表示します)。実際の試合のみが必要な場合は、left outer joininner joinに変更してください。範囲のみが必要な場合は、出力にvalを含めないでください(SELECT句内)。

with 
    ranges_table (start_range, end_range) as (
     select 475747000, 475747999 from dual union all 
     select 476367781, 476367782 from dual union all 
     select 454313059, 454313069 from dual 
    ), 
    list_of_values (val) as (
     select column_value from table(sys.odcinumberlist 
       (475747003, 476367781, 454313069, 454545398)) 
    ) 
select l.val, r.start_range, r.end_range 
from list_of_values l left outer join ranges_table r 
          on l.val between r.start_range and r.end_range 
; 

VAL  START_RANGE END_RANGE 
--------- ----------- --------- 
454313069 454313059 454313069 
454545398 
475747003 475747000 475747999 
476367781 476367781 476367782 

あなただけ(ちょうど上記の表からVAL列をドロップするよりも理にかなって)DISTINCTマッチング範囲が必要な場合は、代わりにこのような何か行うことができます:

select start_range, end_range 
from ranges_table 
where exists (select val 
       from list_of_values 
       where val between start_range and end_range 
      ) 
; 
関連する問題