想象一下,我们有一个带有日志表和类型表的数据库。我想进行查询,以确定UserX是否具有某些类型的日志的条目。假设UserX已记录type_1
和type_2
,但没有记录type_3
。我想编写一个简单的查询,看看这是对还是错。
起初我尝试过类似的事情:
SELECT * FROM logs AS l
INNER JOIN types AS t
ON t.id = l.type_id
WHERE t.name = "type_1"
AND t.name = "type_2"
AND t.name != "type_3";
但是我很快意识到不可能这样做,因为t.name
不能有多个值。我现在尝试了很多不同的方法,但是似乎找不到适合我的方法。我确定解决方案非常简单,目前暂时看不到。
希望有人可以指出我正确的方向。
我在此小提琴中制作了一个简单的测试数据库,用于测试和示例:https://www.db-fiddle.com/f/nA6iKgCcJwKnXKsxaNvsLt/0
答案 0 :(得分:2)
带有条件聚合的一个选项。
SELECT l.userID
FROM logs AS l
JOIN types AS t ON t.id = l.type_id
GROUP BY l.userID
HAVING COUNT(DISTINCT CASE WHEN t.name IN ('type_1','type_2') THEN t.name END) = 2
AND COUNT(DISTINCT CASE WHEN t.name = 'type_3' THEN t.name END) = 0
答案 1 :(得分:1)
您可以像Vamsi一样进行操作,但是如果您希望使用易于理解的SQL,则可以这样做:
SELECT * FROM logs AS l
INNER JOIN types AS t
ON t.id = l.type_id
WHERE true
AND EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 1)
AND EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 2)
AND NOT EXISTS (SELECT 1 FROM logs ll WHERE l.user_id = ll.user_id AND type_id = 3)
答案 2 :(得分:1)
我不建议为此目的使用count(distinct)
。可能很贵。我会简单地做:
SELECT l.userId
FROM logs l INNER JOIN
types t
ON t.id = l.type_id
WHERE t.name IN ('type_1', 'type_2', 'type_3')
GROUP BY l.userId
HAVING SUM(t.name = 'type_1') > 0 AND -- at least one
SUM(t.name = 'type_2') > 0 AND -- at least one
SUM(t.name = 'type_3') = 0 ; -- none