Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude whole group based on single value

Table T

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

I want the output to have only those CID groups where Code <> 'C'

Desired Output:

CID  Code
3     A
3     D

Query Attempt:

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

But this will exclude rows where Code = C, not the entire groups where Code = C. Not sure how GROUP BY could work here

like image 431
AS91 Avatar asked Oct 06 '16 21:10

AS91


People also ask

How do I exclude a specific result in SQL?

In SQL, in order to EXCLUDE certain rows from being returned by a SELECT query, we use some restricting or excluding conditions based on some criteria. EXCLUDE conditions in SQL usually appear in the WHERE clause of the statement or in the HAVING clause of an aggregate query.

How do I exclude multiple values in SQL?

To exclude multiple values to be fetched from a table we can use multiple OR statements but when we want to exclude a lot of values it becomes lengthy to write multiple AND statements, To avoid this we can use the NOT IN clause with the array of values that need to be excluded with the WHERE statement.

Does GROUP BY exclude NULL?

Group functions ignore the NULL values in the column. To enforce the group functions ti include the NULL value, use NVL function.


2 Answers

One method uses 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'
                 );

Another method uses a window function:

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;
like image 153
Gordon Linoff Avatar answered Sep 30 '22 02:09

Gordon Linoff


One more variant, which produces the same execution plan as the one with 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'
    )
;

Inner query gives a list of all CID groups that have at least one C. Main query returns all rows from all other groups, not included in the inner list.

I don't understand why you put DISTINCT in the query. If the data doesn't have duplicates, DISTINCT would do extra sort that does nothing useful, since there are no duplicates already. If the data has duplicates - do you really want to get rid of them?

like image 42
Vladimir Baranov Avatar answered Sep 30 '22 02:09

Vladimir Baranov