在SQL中使用表行连接值列表

时间:2014-04-29 23:29:09

标签: sql sql-server oracle

假设我有一个值列表,例如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运算符的情况下执行此操作?

6 个答案:

答案 0 :(得分:39)

如果在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是否有类似的构造

答案 1 :(得分:4)

this source采用了以下oracle解决方案。基本思想是利用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以查看是否有效。

答案 2 :(得分:2)

迟到了,但是对于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

答案 3 :(得分:1)

假设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实施。

fiddle

答案 4 :(得分:0)

假设您的值为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

答案 5 :(得分:0)

要获取部分输出所需的序号(此方法消除了要键入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