【问题标题】:Find the records which are not successful查找不成功的记录
【发布时间】:2017-12-29 05:49:14
【问题描述】:

我是 SQL 查询的初学者。我需要在表中找到尚未成功的 Error1 记录。

我的桌子是这样的:

ImportId    LineNumber   Status
---------------------------------
195             6        Success
195             5        Success
195             5        Error1
195             6        Error1
195             7        Error1
195             8        Success
195             9        Error2

此查询不返回 importId 为 195 且行号为 7 的行

select * 
from Table1 
where not exists (select success.ImportID, success.LineNumber 
                  from Table1 success 
                  join 
                      (select ImportID, LineNumber
                       from Table1 
                       where status = 'Error1') overlap on overlap.linenumber = success.LineNumber 
                                                        and overlap.ImportID = success.ImportID
                  where success.status = 'success')

【问题讨论】:

  • 运行子查询,看看会出现什么。
  • 感谢排版,下次我会多练习一点。
  • 子查询显示为 195 5 195 6
  • 感谢您的回复。我只寻找没有匹配成功的 Error1 记录。
  • 我还不能投票,但答案和查询非常有帮助。我已经标记了一个首先对我有用的答案。再次感谢您。

标签: sql sql-server tsql


【解决方案1】:

这是一个更简单的方法,EXCEPT

SELECT ImportID, LineNumber
FROM Table1
WHERE Status = 'Error1'

EXCEPT

SELECT ImportID, LineNumber
FROM Table1
WHERE Status = 'Success'

注意:EXCEPTUNION 一样,将创建不同的结果集。如果您不需要或不想要不同的结果,那么EXISTS 会表现得更好。

【讨论】:

  • 这也会给我 Error2 记录。实际上,在我们的系统中,Error1 记录已重试,并且在成功或出现其他错误后我们停止重试。
  • @OscarAnad 不确定您的意思,它仅过滤到上半部分的 Error1 记录。它将仅显示具有Error1 而没有Success 的记录
  • 不会得到Error2记录,因为顶部查询中有WHERE Status = 'Error1'。它可以正常工作,但在性能方面,这将不如 NOT EXISTS 解决方案。
  • @NenadZivkovic 我认为在这种情况下它会完全相同。 EXISTS 的答案将与将在 EXCEPT 中进行比较的两个字段相关联。我忽略了什么吗?
  • @AaronDietz EXECPT 将在加入两个结果集之前添加不必要的排序 - 如果在 ORDER BY ImportID, LineNumber 解决方案中有 ORDER BY ImportID, LineNumber 也是如此。您可以同时运行它们并自己检查执行计划。
【解决方案2】:

你把它复杂化了,只需选择那些有错误的那些不存在相同记录的成功

SELECT * 
FROM Table1 t1
WHERE t1.status = 'Error1'
AND NOT EXISTS 
(
   SELECT *
   FROM Table1 s
   WHERE s.Status = 'Success'
   AND s.ImportID = t1.ImportID
   AND s.LineNumber = t1.LineNumber
);

【讨论】:

  • 我不敢相信它的结构可以这么好,非常感谢!
【解决方案3】:

我认为这是你想要的:

select t1.*
from table1 t1
where t1.status = 'Error1' and 
      not exists (select 1
                  from table1 tt1
                  where tt1.importid = t1.importid and tt1.linenumber = t1.linenumber and
                        tt1.status = 'Success'
                );

【讨论】:

    【解决方案4】:

    您可以使用 [error1 table] 的简单左连接 left join [success table] 并挑选出在 [success table] 中找不到的记录。检查以下查询。

    SELECT E.IMPORTID, E.LINENUMBER, E.STATUS
    FROM
    (SELECT IMPORTID, LINENUMBER FROM TABLE1 WHERE STATUS = 'Error1') E
    LEFT JOIN
    (SELECT IMPORTID, LINENUMBER FROM TABLE1 WHERE STATUS = 'Success') S
    ON E.IMPORTID = S.IMPORTID AND E.LINENUMBER = S.LINENUMBER
    WHERE S.IMPORTID IS NULL AND S.LINENUMBER IS NULL;
    

    【讨论】:

      【解决方案5】:
      select ImportID, LineNumber
      from Table1 t1
      where Status in ('Success', 'Error1')
      group by ImportID
      having max(Status) = 'Error1'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-06-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多