我試圖加入3個表格,其中第三個表格包含對第二個和第一個的引用;我希望這些參考文獻的結果。但是,如果第三個表格引用第一個表格,我不需要第二個表格的結果。加入第三個表格,直接與第一個或通過中介
這很難解釋,所以我已經說明了我以下的例子。
第一個select語句產生6行;我明白爲什麼,但那不是我所追求的。
第二個2給出我以後的結果,但是他們有一個代碼味道。任何人都可以提出一個更好的方法來實現相同的輸出嗎?
參見SQL小提琴:http://sqlfiddle.com/#!3/8029cc/1
--code to setup my example
declare @t1 table (id bigint, val nvarchar(10))
declare @t2 table (id bigint, t1Id bigint, val2 nvarchar(10))
declare @t3 table (id bigint, t1Id bigint, t2Id bigint, val3 nvarchar(10))
insert @t1 (id, val) values (1, '1.1')
insert @t2 (id, t1Id, val2)
values (1, 1, '2.1')
,(2, 1, '2.2')
,(3, 1, '2.3')
insert @t3 (id, t1Id, t2Id, val3)
values (1, 1, null, 'XXX')
, (1, null, 1, '3.1')
,(2, null, 2, '3.2')
,(3, null, 3, '3.3')
。
--this produces 6 results; I only want 4
select *
from @t1 t1
left outer join @t2 t2
on t2.t1Id = t1.Id
left outer join @t3 t3
on t3.t2Id = t2.Id
or t3.t1Id = t1.id
。
--this works, but means repeating myself; which I'd prefer not to do if possible (could use a cte to make that simpler in the real world scenario, but still not ideal)
select t1.id, t2.id, t3.id, t1.val, t2.val2, t3.val3
from @t1 t1
left outer join @t2 t2
on t2.t1Id = t1.Id
left outer join @t3 t3
on t3.t2Id = t2.Id
union all
select t1.id, null, t3.id, t1.val, null, t3.val3
from @t1 t1
left outer join @t3 t3
on t3.t1Id = t1.id
。
--this works too, but feels very hacky
select t1.id, t2.id, t3.id, t1.val, t2.val2, t3.val3
from @t1 t1
left outer join
(
select id, t1id, val2
from @t2
union all
select null, null, null
) t2
on coalesce(t2.t1Id,t1.Id) = t1.Id
left outer join @t3 t3
on t3.t2Id = t2.Id
or (t3.t1Id = t1.id and t2.Id is null)
更新
我只是想另一個解決方案,感覺有點清潔除以上的;儘管我仍然有點不舒服...
--another option; again slightly hacky
select id, id2, id3, val, val2, val3
from
(
select t1.id
, case when t3.t1Id = t1.id then null else t2.id end id2
, t3.id id3
, t1.val
, case when t3.t1Id = t1.id then null else t2.val2 end val2
, t3.val3
, row_number() over (partition by t1.id order by case when t3.t1Id = t1.id then null else t2.id end, t3.id) x
from @t1 t1
left outer join @t2 t2
on t2.t1Id = t1.Id
left outer join @t3 t3
on t3.t2Id = t2.Id
or t3.t1Id = t1.id
) t
where id2 is not null or x = 1
ps。對於任何人使用上述找到他們的問題的解決方案,我發現,在大多數的現實情況下,上面的第一個工作解決方案(即't1加入t2連接t3'和't1連接t3'的結果之間的'union all'' )是最高效的。 – JohnLBevan
更新:迄今爲止的大多數答案都建議將t3移至FROM。如果我在測試日期添加新的值; 'insert @ t1(id,val)values(1,'1.1'),(8,'8.1')'你會看到這個方法的一個問題。即我們不再有來自t1的每個值。 – JohnLBevan