减少自我联接

时间:2015-06-24 16:20:45

标签: sql sql-server sql-server-2008

考虑以下表格

create table temp1(id int, value1 varchar(20), value2 varchar(20),value3 varchar(20))
insert into temp1 values (100,'apple','orange','mango')
insert into temp1 values(101,'banana','grapes','mango')
insert into temp1 values(102,'litchi','grapes','apple')

create table temp2(id int, value varchar(20))
insert into temp2 values(100,'banana')
insert into temp2 values(100,'grapes')
insert into temp2 values(100,'apple')
insert into temp2 values(101,'banana')
insert into temp2 values(101,'litchi')
insert into temp2 values(102,'mango')
insert into temp2 values(102,'orange')
insert into temp2 values(102,'banana')

现在,以下查询将temp1中的value1,value2,value3列与temp2中的value列和来自两个表的id连接起来:

select t1.id,t2.value value1,t3.value value2,t4.value value3 from temp1 t1
left join
temp2 t2 on (t1.value1=t2.value) and (t1.id = t2.id)
left join
temp2 t3 on (t1.value2=t3.value) and (t1.id = t3.id)
left join
temp2 t4 on (t1.value3=t4.value) and (t1.id = t4.id)

输出

    id  value1  value2  value3
1   100 apple   NULL    NULL
2   101 banana  NULL    NULL
3   102 NULL    NULL    NULL

有没有办法重写查询,以便我不必将temp1和temp2连接3次?实际上temp2是一个有很多行的表,所以不要打3次。提前谢谢!

2 个答案:

答案 0 :(得分:2)

您可以在联接中使用OR语句。我更新了这个来处理value2和value3字段:

select  t1.id
        , case
            when t1.value1=t2.value then t2.value
            else null
        end as value1
        , case
            when t1.value2=t2.value then t2.value
            else null
        end as value2
        , case
            when t1.value3=t2.value then t2.value
            else null
        end as value3
from temp1 t1
left join
temp2 t2 on ((t1.value1=t2.value) and (t1.id = t2.id))
            OR ((t1.value2=t2.value) and (t1.id = t2.id))
            OR ((t1.value3=t2.value) and (t1.id = t2.id))

答案 1 :(得分:1)

UNPIVOT-JOIN-PIVOT 此技术可以过滤交叉表,而无需单独操作所有列。

SELECT *
FROM (
  SELECT t1.id,t1.col,t2.value
  FROM temp1
  UNPIVOT(value FOR col IN (value1,value2,value3)) t1
  LEFT JOIN temp2 t2 ON t1.id = t2.id and t1.value = t2.value
) t3
PIVOT(MAX(value) FOR col IN (value1,value2,value3)) t4