2012-12-21 39 views
8

我有以下兩個表。我使用SQL Server 2008 R2的t-sql中的左外連接

Create table #tmp1 (
a char(1) 
) 

Create table #tmp2 (
id int, 
a char(1), 
val int 
) 

insert #tmp1 values ('A') 
insert #tmp1 values ('B') 
insert #tmp1 values ('C') 

insert #tmp2 values (1, 'A', 10) 
insert #tmp2 values (1, 'B', 20) 
insert #tmp2 values (2, 'A', 30) 
insert #tmp2 values (2, 'C', 40) 

select * from #tmp1 t1 left outer join #tmp2 t2 on t1.a = t2.a 
order by t2.id 

返回的結果集

A 1 A 10 
B 1 B 20 
C 2 C 40 
A 2 A 30 

我想有以下結果集

A  1 A  10 
B  1 B  20 
C  1 null null 
A  2 A  30 
B  2 null null 
C  2 C  40 

現在我通過創建acheiving這一個交叉連接這樣的新表,然後做外連接

select * into #tmp3 from #tmp1 cross join (select distinct ID from #tmp2) t 
select * from #tmp3 t1 left outer join #tmp2 t2 on t1.a = t2.a and t1.id = t2.id 

有沒有更好的方法來做到這一點?

謝謝

+0

+1的設置SQL –

+1

的設置SQL是好的,那麼你可以使用此解決方案。但是,您應該在查詢中避免使用「*」,因爲需要弄清楚哪些列來自哪些表。 –

回答

3

爲了得到你想要的,你需要一個「駕駛」表。也就是說,您需要所有組合的完整列表,然後加入其他表以獲得匹配。這裏有一種方法:

select t1.a, t2.* 
from (select t1.a as a, t2.id as id 
     from (select distinct a from #tmp1 t1) t1 
      cross join 
      (select distinct id from #tmp2 t2) t2 
    ) driving left outer join 
    #tmp1 t1 
    on t1.a = driving.a left outer join 
    #tmp2 t2 
    on t2.id = driving.id and 
     t2.a = driving.a 
order by t2.id 
+0

是的。我正在做類似於你正在做的事情。我希望也許有一些新的SQL子句,如交叉應用,外部應用等,這將使代碼更簡單。 – Satfactor

+1

戈登是對的,爲了做到這一點,你需要有一個「駕駛」表。我們的代碼非常類似於這個來完成同樣的事情。使這種類型的查詢工作並不困難。 – CodeLikeBeaker

0

你所尋找的是在#tbl2的id列在#TBL1值和值的笛卡爾積。由於#tbl2.id中的值不是唯一的,因此爲每個#tbl2.id值設置一行附加表可能會更好。如果這不是一個選項,使用這個代替

Create table #tmp1 (
a char(1) 
) 

Create table #tmp2 (
id int, 
a char(1), 
val int 
) 

Create table #tmp3 (
id int 
) 

insert #tmp1 values ('A') 
insert #tmp1 values ('B') 
insert #tmp1 values ('C') 

insert #tmp3 values (1) 
insert #tmp3 values (2) 

insert #tmp2 values (1, 'A', 10) 
insert #tmp2 values (1, 'B', 20) 
insert #tmp2 values (2, 'A', 30) 
insert #tmp2 values (2, 'C', 40) 

SELECT t3.id,t1.a,t2.val 
FROM #tmp1 AS t1 
CROSS JOIN #tmp3 AS t3 
LEFT OUTER JOIN #tmp2 AS t2 
ON t1.a = t2.a AND t3.id = t2.id 
ORDER BY t3.id, t1.a; 

SELECT t3.id,t1.a,t2.val 
FROM #tmp1 AS t1 
CROSS JOIN (SELECT DISTINCT id FROM #tmp2) AS t3 
LEFT OUTER JOIN #tmp2 AS t2 
ON t1.a = t2.a AND t3.id = t2.id 
ORDER BY t3.id, t1.a;