使用 SQL 查找仅与特定列表中的值匹配的行

use*_*543 4 query except

我有一张这样的表:

  Id    Status
  --    -----------
  1     Closed
  1     In progress
  2     Rejected
  3     Cancelled
  4     Rejected
  4     Closed
  5     In progress
Run Code Online (Sandbox Code Playgroud)

我想说明,有行Status封闭拒绝取消。但是,我想排除具有不同状态值的 ID,即使它们也具有这三个中的任何一个。

所以,对于我的例子,我希望输出是这样的:

  Id    Status
  --    ---------
  2     Rejected
  3     Cancelled
  4     Rejected
  4     Closed
Run Code Online (Sandbox Code Playgroud)

我的查询应该是什么样的?

Mar*_*ith 8

一种方法是使用NOT EXISTS.

SELECT *
FROM   YourTable T1
WHERE  Status IN ( 'Closed', 'Rejected', 'Cancelled' )
       AND NOT EXISTS (SELECT *
                       FROM   YourTable T2
                       WHERE  T2.Id = T1.Id
                              AND T2.Status NOT IN ( 'Closed', 'Rejected', 'Cancelled' )) ;
Run Code Online (Sandbox Code Playgroud)

或者,如果您的 DBMS 支持窗口聚合,则另一种方法..

SELECT Id,
       Status
FROM   (SELECT *,
               COUNT(CASE WHEN Status NOT IN ('Closed','Rejected','Cancelled') 
                             THEN 1 END) 
                     OVER (PARTITION BY Id) C
        FROM   YourTable) D
WHERE  Status IN ( 'Closed', 'Rejected', 'Cancelled' )
       AND C = 0 ;
Run Code Online (Sandbox Code Playgroud)

另一个选项使用EXCEPT

SELECT * 
FROM YourTable 
WHERE Id IN 
      ( SELECT Id FROM YourTable 
        WHERE Status IN ( 'Closed', 'Rejected', 'Cancelled' ) 
      EXCEPT 
        SELECT Id FROM YourTable 
        WHERE Status NOT IN ( 'Closed', 'Rejected', 'Cancelled' )
      ) ;
Run Code Online (Sandbox Code Playgroud)