【问题标题】:TSQL - excluding the rows that matches with temp tableTSQL - 排除与临时表匹配的行
【发布时间】: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

【问题讨论】:

    标签: sql sql-server tsql


    【解决方案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)
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-07-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多