2009-01-23 113 views
13

我有3個表,我不得不內部連接表A與表B,但表A和表C之間的左外SQL服務器 - 結合外部和內部連接

我可以結合外部和內部的加入同樣的查詢?我可以嵌套查詢並獲得所需的結果,但我無法在同一查詢中同時執行兩個連接。看起來在其他SQL語言中,加入的順序很重要。這是SQL Server的情況嗎?


好的,這是場景。

考慮3個表格。表A,表F,表D.

我將需要記錄集包含D中的所有行,而不管它是否存在於F中(在它與A連接後)。所以,想到一個外部連接。我需要的是:

  1. 先做A和F之間的內連接來得到一組(這可能是一個空集)
  2. 然後做一個外連接,在與d(1)記錄

回答

4

當然,你可以做同樣的查詢聯接: -

FROM TableA a 
INNER JOIN Table b ON a.TableA_ID = b.TableA_ID 
LEFT OUTER JOIN Table c ON a.TableA_ID = c.TableA_ID 
+0

這並沒有給出表D上的所有行(即你稱之爲c) – Paparazzi 2018-03-09 15:09:25

0

是的,你都可以做的是相同的查詢,是的順序是非常重要的。

13

如果我理解正確的話,你想是這樣的:

select 
    * 
from 
    a 
    left outer join c 
     inner join b on c.bID = b.ID 
    on a.cID = c.ID 
+3

棘手!如果您將「on.cID = c.ID」移動到「left outer join c」的下方,這不會產生相同的結果,或者我只是錯過了某些東西?這種行爲是否記錄在某處?我沒有意識到這一點並不需要直接關注連接。 – Brandon 2015-08-18 02:29:12

+0

我認爲你有一個和一個倒退 – Paparazzi 2018-03-09 15:10:30

1

從你的跟進,這聽起來像你想有一個「有條件」內連接。

基本上,「如果A和B有記錄,INNER JOIN to C」。

但是,您可能會遇到問題,其中查詢中的INNER JOIN未顯示記錄,其中A沒有與B或C關聯的記錄。如果它們位於相同的「範圍」中,INNERS將始終運行,你不能有條件地讓他們根據他們的順序運行。

您必須使用兩個LEFT連接並篩選出您不需要的記錄,或者使用視圖來限制INNER JOIN。

Ex。 左加入vw_MyView ON A.ID = vw_MyView.A_ID

其中MyView的表B和C與您的INNER JOIN。這將允許INNER JOIN在視圖內部運行,然後您可以LEFT JOIN結果。

2

該訂單應該不是的問題。

Venn Diagram

下面是來自於維基共享維恩圖。無論查詢順序如何,您將獲得圓A和B之間的重疊,其中C不包含A和B的組合的C列的空值。

0

問題可能並不是特定的連接(Anthony向你展示瞭如何處理你向我們描述的內容)。記住人們在使用左連接時經常會遇到問題,因爲他們試圖在where子句中引用連接右側的表,從而將它從外連接轉換爲到內部聯接(除非您正在查找第二個表字段爲空的記錄,這會爲第一個表中的記錄提供記錄,而不是第二個表中的記錄)。

如果我們說出您使用的實際代碼並非產生期望的結果以及一些樣本數據和樣本結果,我們可以幫助您更好。

7

對於我來說,我需要把表的別名爲我的查詢才能正常工作:

SELECT * FROM ("purchased_items" p1 
    INNER JOIN "purchase_orders" po1 ON (po1."id" = p1."purchase_order_id")) AS p4 
LEFT OUTER JOIN (purchased_items p2 
     INNER JOIN "purchase_orders" po2 ON (po2."id" = p2."purchase_order_id")) AS p5 
ON (p4.item_variant_id = p5.item_variant_id AND p4.delivery_date < p5.delivery_date) 
WHERE p5.delivery_date IS NULL AND p4.delivered <> 0 
0

這在1至零或多個出現,其中許多具有FK。

兩種方法
秩序on
outer參加最後

不幸你改變表名。我會用後面的名字。

declare @TableD TABLE (PeopleID int primary key, Name varchar(10)); 
INSERT INTO @TableD VALUES 
     (1, 'Chris') 
    , (2, 'Cliff') 
    , (3, 'Heather'); 

declare @TableA TABLE (ThingID int primary key, ThingName varchar(10)) 
INSERT INTO @TableA VALUES 
     (14, 'Bike') 
    , (17, 'Trailer') 
    , (18, 'Boat'); 

declare @TableF TABLE (PeopleID int, ThingID int, primary key (PeopleID, ThingID)); 
INSERT INTO @TableF VALUES 
     (1, 18) 
    , (1, 17) 
    , (2, 14); 

SELECT D.Name, A.ThingName 
FROM @TableD D 
LEFT JOIN @TableF F 
    JOIN @TableA A 
     ON A.ThingID = F.ThingID 
    ON F.PeopleID = D.PeopleID 
order by D.Name, A.ThingName; 

SELECT D.Name, A.ThingName 
FROM @TableF F 
JOIN @TableA A 
    ON A.ThingID = F.ThingID 
right join @TableD D 
    ON D.PeopleID = F.PeopleID 
order by D.Name, A.ThingName; 

Name  ThingName 
---------- ---------- 
Chris  Boat 
Chris  Trailer 
Cliff  Bike 
Heather NULL