我的数据库中有一个表:
Name | Element
1 2
1 3
4 2
4 3
4 5
我需要进行一个查询,对于许多参数,将选择右侧的Name和仅这些值的Name值。 例如。: 参数是2和3,查询应该只返回1而不是4(因为4也有5)。对于参数2,3,5,它应该返回4.
我的查询如下:
SELECT name FROM aggregations WHERE (element=2 and name in (select name from aggregations where element=3))
我必须添加到此查询中以使其不返回4?
答案 0 :(得分:8)
一种简单的方法:
SELECT name
FROM aggregations
WHERE element IN (2,3)
GROUP BY name
HAVING COUNT(element) = 2
如果您想添加更多内容,则需要同时更改IN (2,3)
部分和HAVING
部分:
SELECT name
FROM aggregations
WHERE element IN (2,3,5)
GROUP BY name
HAVING COUNT(element) = 3
更强大的方法是检查您的集合中没有的所有内容:
SELECT name
FROM aggregations
WHERE NOT EXISTS (
SELECT DISTINCT a.element
FROM aggregations a
WHERE a.element NOT IN (2,3,5)
AND a.name = aggregations.name
)
GROUP BY name
HAVING COUNT(element) = 3
但是,这不是很有效率。
答案 1 :(得分:1)
创建一个临时表,用你的值填充它并查询如下:
SELECT name
FROM (
SELECT DISTINCT name
FROM aggregations
) n
WHERE NOT EXISTS
(
SELECT 1
FROM (
SELECT element
FROM aggregations aii
WHERE aii.name = n.name
) ai
FULL OUTER JOIN
temptable tt
ON tt.element = ai.element
WHERE ai.element IS NULL OR tt.element IS NULL
)
这比使用COUNT(*)
更有效,因为它会在找到没有匹配的第一行时停止检查name
(在aggregations
或在temptable
)
答案 2 :(得分:0)
这未经过测试,但通常我会在我的where子句中使用查询来执行此操作以获取少量数据。请注意,这对于大量记录计数效率不高。
SELECT ag1.Name FROM aggregations ag1
WHERE ag1.Element IN (2,3)
AND 0 = (select COUNT(ag2.Name)
FROM aggregatsions ag2
WHERE ag1.Name = ag2.Name
AND ag2.Element NOT IN (2,3)
)
GROUP BY ag1.name;
这说“给我所有拥有我想要的元素的名字,但没有我不想要的元素的记录”