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

Posted

技术标签:

【中文标题】TSQL - 排除与临时表匹配的行【英文标题】:TSQL - excluding the rows that matches with temp table 【发布时间】:2017-09-18 17:10:57 【问题描述】:

我需要有关 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 的临时表

TemplateID  DocumentID  
---------------------------
2           NULL
NULL        33

我想从 @tmpDetail 表中选择 A、B 和 C 组中没有匹配的 TemplateID 和 DocumentID 的行

所以选择查询应该返回详细 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

【问题讨论】:

【参考方案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))

【讨论】:

【参考方案2】:
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

【讨论】:

【参考方案3】:

您可以使用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)

【讨论】:

以上是关于TSQL - 排除与临时表匹配的行的主要内容,如果未能解决你的问题,请参考以下文章

TSQL将N插入固定临时表

如何从一个表中删除与另一表匹配的行?

TSQL 将数据库 BLOB 提取到临时表中

MySQL left join操作中 on与where放置条件的区别

对于表中的行,将行保存在临时表中以在 plpgsql 的选择查询中使用其数据

从 Excel 运行的 SQL 不能使用临时表