TSQL - 排除与临时表匹配的行

时间:2017-09-18 17:10:58

标签: sql sql-server tsql

我需要SQL SELECT查询的帮助。

我在下面有[Details] sql表。我想选择具有匹配组ID且在给定临时表中不存在的行

DetailID   GroupID     TemplateID   DocumentID
------------------------------------------------------
1            A            2             NULL
2            A            NULL          33
3            A            10            NULL *

4            B            NULL          33
5            B            4             NULL *

6            C            2             NULL
7            C            4             NULL *
8            C            NULL          55   *

@tmpDetails - 具有TemplateID和DocumentID

的Templarary表
TemplateID  DocumentID  
---------------------------
2           NULL
NULL        33

我想选择A,B和C组中的行,并且没有来自@tmpDetail表的匹配的TemplateID和DocumentID

所以select查询应返回详细ID为3,5,7,8

的行

下面的查询不会返回任何内容

SELECT * from Details D
WHERE D.GroupID IN ('A','B','C') AND NOT EXISTS
(SELECT d2.DetailID FROM Details d2 
 JOIN @tmpDetails t ON  d2.TemplateID IS NOT NULL 
       AND d2.TemplateID = t.TemplateID 
       OR d2.DocumentID IS NOT NULL AND d2.DocumentID = t.DocumentID)

无论JOIN中的条件是什么,它应该是where条件,但我确定如何组成SQL

3 个答案:

答案 0 :(得分:1)

您没有将嵌套查询与主表(D)连接。

你可以摆脱加入并执行此操作:

SELECT * FROM Details D 
WHERE D.GroupID IN ('A','B','C') AND NOT EXISTS
   (SELECT 1 FROM @tmpDetails t 
    WHERE  (D.TemplateID IS NOT NULL AND D.TemplateID = t.TemplateID) OR 
           (D.DocumentID IS NOT NULL AND D.DocumentID = t.DocumentID))

答案 1 :(得分:1)

SELECT D.*
FROM
    Details D
    OUTER APPLY
    (
        SELECT TOP 1 1 Match
        FROM @tmpDetails T
        WHERE
            D.TemplateID = T.TemplateID
            OR D.DocumentID = T.DocumentID
    ) T
WHERE
    D.GroupID IN ('A','B','C')
    AND T.Match IS NULL

答案 2 :(得分:1)

您可以使用NOT EXISTS和子查询与INTERSECT来处理NULL值:

SELECT * FROM Details D
WHERE D.GroupID IN ('A', 'B', 'C') 
  AND NOT EXISTS (SELECT TemplateID, DocumentID FROM @tmpDetails INTERSECT 
                  SELECT D.TemplateID, D.DocumentID)