2012-02-06 120 views
0

我有一個相當複雜的查詢非常模擬測試查詢我有以下:條件INNER JOIN在SQL Server

SELECT C.* 
    FROM Customer C 
     INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId 
     INNER JOIN Address A ON CD.DetailID = A.DetailID 
     INNER JOIN Group G ON C.CustomerId = G.CustomerId --Join only when C.code = 1 
     INNER JOIN GroupDetail D ON G.GroupId = D.DetailId --Join only when C.code = 1 
WHERE G.Active = 1 AND  --Only when C.code = 1 
     D.code = '1' AND  --Only when C.code = 1 
     C.Id = @customerId 

我想對Group GGroupDetail DINNER JOIN S(和ofcourse沒有他們根據表列C.code = 1

WHERE條件我更換了INNER JOIN s的LEFT OUTER JOIN S表示兩個連接條件,但結果集不是預期

如何有條件地做了JOIN

+1

'INNER JOIN Group G ON C.CustomerId = G.CustomerId AND C.code = 1'? – 2012-02-06 22:17:35

+0

您可以發佈一些示例數據,期望的結果,以及如何使用左連接獲得的結果集「不是預期的」?瞭解*預期會使得解決問題更容易。 – 2012-02-06 22:41:24

+0

一個客戶可以有多少個代碼,他自然要求客戶。客戶ID在客戶表中是唯一的?如果你只想在代碼= 1的情況下進行連接,但不關心它是否會成爲我會走的路。 – 2012-02-06 22:51:22

回答

4
SELECT C.* 
    FROM Customer C 
     INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId 
     INNER JOIN Address A ON CD.DetailID = A.DetailID 
     LEFT OUTER JOIN Group G ON C.CustomerId = G.CustomerId 
     LEFT OUTER JOIN GroupDetail D ON G.GroupId = D.DetailId 
WHERE ((G.Active = 1 AND C.code = 1) OR G.Active IS NULL) AND 
     ((D.code = '1' AND C.code = 1) OR D.code IS NULL) AND 
     C.Id = @customerId 

我猜你不包括IS NULL檢查之前,所以你從來沒有看到行C.code <> 1?

你應該檢查NULL永遠不會爲空的字段。這幾乎總是'id',但目前還不清楚你是否擁有G.id或D.id。

+0

我認爲很好的猜測 – 2012-02-06 23:22:53

0

這會是一個半連接,只有當代碼爲1

SELECT C.* 
FROM Customer C 
    INNER JOIN CustDetail CD 
     ON C.CustomerId = CD.CustomerId 
    INNER JOIN Address A 
     ON CD.DetailID = A.DetailID 
WHERE 
     C.Id = @customerId AND 
     (c.code != 1 OR 
     EXISTS(
     SELECT NULL 
     FROM Group G 
      JOIN GroupDetail D ON G.GroupId = D.DetailId 
     WHERE 
      C.CustomerId = G.CustomerId AND 
      G.Active = 1 AND 
      D.code = '1' 
    )) 
0

我猜你想要的只是一個更緊的ON子句和一個複合條件。

SELECT C.* 
    FROM Customer C 
     INNER JOIN CustDetail CD ON C.CustomerId = CD.CustomerId 
     INNER JOIN Address A ON CD.DetailID = A.DetailID 
     -- the next two joins happen only when c.code=1 
     -- their columns will be null when there is no match. 
     LEFT JOIN Group G ON C.CustomerId = G.CustomerId AND C.Code = 1 
     LEFT JOIN GroupDetail D ON G.GroupId = D.DetailId AND C.Code = 1 
WHERE C.Id = @customerId AND --always check this 
     -- this condition is true if code is null or code isn't 1, 
     ((C.code IS NULL or C.code <> 1) 
     -- or (if the code is 1), it is true if g.active and d.code 
     OR (G.Active = 1 AND D.code = '1'))