2012-02-06 102 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'))