SQL包括AND排除查询

时间:2014-01-28 18:13:45

标签: sql

我的表 t 包含一个人的姓名和他们拥有的产品:

NAME    PRODUCT
Adam    a
Adam    b
Adam    c
Ben     c
Ben     d
Chris   b
Dave    a
Dave    b
Dave    c
Dave    d
Evan    a
Evan    b
Fred    a

我想要一个SQL查询,当该人有产品a或b或两者时返回NAME,并且没有产品c和d(也不是e,f,...):

NAME
Chris
Evan
Fred

我正在使用的实际“没有”列表很长,所以如果可能的话,我希望避免输入要排除的每个产品名称。

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:1)

SELECT DISTINCT name FROM T
WHERE product IN ('a', 'b')
AND name NOT IN (SELECT name FROM T WHERE product IN ('c', 'd', 'e', 'f'))

或者,如果您在另一个表T2中有所有不需要的产品,

SELECT DISTINCT name FROM T
WHERE product IN ('a', 'b')
AND name NOT IN (SELECT name FROM T
                 WHERE product IN (SELECT product FROM T2))

或者,如果不需要的产品实际上除了a和b之外都是其他产品:

SELECT DISTINCT name FROM T
WHERE product IN ('a', 'b')
AND name NOT IN (SELECT name FROM T
                 WHERE product NOT IN ('a', 'b'))

答案 1 :(得分:1)

我知道在T-SQL(MSSQL)中,您可以使用EXCEPT排除结果:

SELECT Name FROM t WHERE Product IN ('a','b')
EXCEPT
SELECT Name FROM t WHERE Product NOT IN ('a','b')

EXCEPT也只会返回DISTINCT个结果 请参阅SQL Fiddle

SELECT之后的第二个EXCEPT查询不必让产品排除硬编码,并且可以从其他表中检索它们,或者您想要的其他内容。

答案 2 :(得分:0)

select Name
from   t
where  exists
       (select * from t as t2
        where  t.Name = t2.Name 
               and Product in ('a','b'))
       not exists
       (select * from t as t2
        where  t.Name = t2.Name 
               and Product not in ('a','b'))

答案 3 :(得分:0)

这是“set-within-sets”查询的示例。我认为最灵活的方法是使用having子句聚合:

select name
from table t
group by name
having sum(case when product in ('a', 'b') then 1 else 0 end) > 0 and
       sum(case when product in ('c', 'd') then 1 else 0 end) = 0;

having子句的第一个条件计算'a''b'的行数。当至少有一行时,“名称”会通过。第二个条件过滤掉您不想要的产品。

如果您只想要'a''b'而没有别的,那么条件是:

having sum(case when product in ('a', 'b') then 1 else 0 end) > 0 and
       sum(case when product not in ('a', 'b') then 1 else 0 end) = 0;