我的表 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
我正在使用的实际“没有”列表很长,所以如果可能的话,我希望避免输入要排除的每个产品名称。
提前感谢您的帮助。
答案 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;