基于单个值排除整个组

时间:2016-10-06 21:46:37

标签: sql sql-server select sql-server-2012 group-by

表T

CID Code
1    A
1    B
1    C
2    C
2    A
2    B
3    A
3    D

我希望输出只包含那些Code <> 'C'

的CID组

期望的输出:

CID  Code
3     A
3     D

查询尝试:

SELECT DISTINCT
         CID
        ,Code
FROM Table T
WHERE Code <> 'C'

但是这将排除Code = C的行,而不是Code = C的整个组。 不确定GROUP BY如何在这里工作

2 个答案:

答案 0 :(得分:4)

一种方法使用not exists

select distinct cid, code
from t
where not exists (select 1
                  from t t2
                  where t2.cid = t.cid and t2.code = 'C'
                 );

另一种方法使用窗口函数:

select distinct cid, code
from (select t.*,
             sum(case when t.code = 'C' then 1 else 0 end) over (partition by cid) as numCs
      from t
     ) t
where numCs = 0;

答案 1 :(得分:2)

另一个变体,它与NOT EXISTS生成相同的执行计划:

SELECT T.CID, T.Code
FROM T
WHERE
    T.CID NOT IN
    (
        SELECT T2.CID
        FROM T AS T2
        WHERE T2.Code = 'C'
    )
;

内部查询提供了至少有一个C的所有CID组的列表。主查询返回所有其他组中的所有行,不包括在内部列表中。

我不明白你为什么把DISTINCT放在查询中。如果数据没有重复,DISTINCT会做额外的排序,没有任何用处,因为没有重复项。如果数据有重复 - 你真的想摆脱它们吗?