web-dev-qa-db-ja.com

SQLで値のリストをテーブル行と結合する

1, 2, 3, 4, 5などの値のリストと、それらの値の一部が列に存在するテーブルがあるとします。以下に例を示します。

id  name
 1  Alice
 3  Cindy
 5  Elmore
 6  Felix

リストのすべての値と値に一致する行の情報を含むSELECTステートメントを作成します。つまり、リストとテーブルの間でLEFT OUTER JOINを実行します、したがって、結果は次のようになります。

id  name
 1  Alice
 2  (null)
 3  Cindy
 4  (null)
 5  Elmore

一時テーブルを作成せずに、または複数のUNION演算子を使用せずにそれを行うにはどうすればよいですか?

23
uncoder

Microsoft SQL Server 2008以降の場合、 Table Value Constructor を使用できます

 Select v.valueId, m.name 
 From (values (1), (2), (3), (4), (5)) v(valueId)
     left Join otherTable m
        on m.id = v.valueId

Oracleに同様の構造があるかどうかわからない

42
Charles Bretana

oracle用の次のソリューションが this source から採用されています。基本的な考え方は、Oracleの階層クエリを活用することです。リストの最大長(以下のサンプルクエリでは100)を指定する必要があります。

   select d.lstid
        , t.name
     from (
               select substr(
                           csv
                         , instr(csv,',',1,lev) + 1
                         , instr(csv,',',1,lev+1 )-instr(csv,',',1,lev)-1
                      )  lstid
                 from (select ','||'1,2,3,4,5'||',' csv from dual)
                    , (select level lev from dual connect by level <= 100)
                where lev <= length(csv)-length(replace(csv,','))-1         
          ) d
left join test  t on ( d.lstid = t.id )
        ;

this sql fiddle をチェックして、動作することを確認してください。

4
collapsar

これには少し遅れますが、Oracleの場合は、次のようなことで値のテーブルを取得できます。

SELECT rownum + 5 /*start*/ - 1 as myval
FROM dual
CONNECT BY LEVEL <= 100 /*end*/ - 5 /*start*/ + 1

...そして、それをテーブルに結合します。

SELECT *
FROM
(SELECT rownum + 1 /*start*/ - 1 myval
FROM dual
CONNECT BY LEVEL <= 5 /*end*/ - 1 /*start*/ + 1) mypseudotable
left outer join myothertable
    on mypseudotable.myval = myothertable.correspondingval
2
EdmCoff

MyTableがテーブルの名前であると仮定すると、次のコードが機能するはずです。

;with x as 
(
  select top (select max(id) from [myTable]) number from [master]..spt_values
),
y as
(select row_number() over (order by x.number) as id
from x)
select y.id,  t.name
from y left join myTable as t
on y.id = t.id;

注意:これはSQL Serverの実装です。

フィドル

1
user353gre3

値が1,2,3,4,5であるテーブルの名前がlist_of_valuesであり、いくつかの値を含むテーブルの名前列がsome_valuesであるとします。

SELECT B.id,A.name
FROM [list_of_values] AS B
LEFT JOIN [some_values] AS A
ON B.ID = A.ID
0
xbb

出力の一部に必要な連続番号を取得する場合(この方法では、n個の数値に対して入力する値が削除されます):

declare @site as int
set @site = 1
while @site<=200
begin
insert into ##table
values (@site)

set @site=@site+1
end

最終出力[上記の手順を投稿]:

select * from ##table
select v.id,m.name from  ##table  as v
left outer join [source_table] m
 on m.id=v.id
0
Amarnadh