Условное ВНУТРЕННЕЕ СОЕДИНЕНИЕ в SQL Server - PullRequest
0 голосов
/ 07 февраля 2012

У меня довольно сложный запрос, который в значительной степени имитирует тестовый запрос, который у меня есть ниже:

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

Я хотел бы сделать INNER JOIN s на Group G и GroupDetail D (и конечноне иметь их в условиях WHERE на основе столбца таблицы C.code = 1

Я заменил INNER JOIN s на LEFT OUTER JOIN s для обоих условий соединения, но набор результатов не соответствует ожидаемому

Как условно сделать JOIN

Ответы [ 3 ]

4 голосов
/ 07 февраля 2012
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 голосов
/ 07 февраля 2012

Я предполагаю, что вам нужно только более жесткое предложение 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'))
0 голосов
/ 07 февраля 2012

Это будет полусоединение, только когда код равен 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'
      ))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...