[英]SQL query where ALL records in a join match a condition?
I have what seems to be a simple problem, but can not figure out the proper solution via SQL. 我有一个似乎是一个简单的问题,但无法通过SQL找出正确的解决方案。 I'm using postgresql specifically.
我特意使用postgresql。
Take the following: 请考虑以下事项:
SELECT * FROM users INNER JOIN tags ON (tags.user_id = users.id) WHERE tags.name IN ('word1', 'word2')
This does not do what I need. 这不符合我的需要。 I want to find users whose tags are ONLY included in the list.
我想找到标签仅包含在列表中的用户。 If the user has a tag that is not in the list, the user should not be included.
如果用户的标签不在列表中,则不应包括该用户。
'user1' tags: word1, word2, word3 'user1'标签:word1,word2,word3
'user2' tags: word1 'user2'标签:word1
'user3' tags: word1, word2 'user3'标签:word1,word2
Given: word1 and word2. 给定:word1和word2。 I want to prepare a query that returns 'user2' and 'user3'.
我想准备一个返回'user2'和'user3'的查询。 'user1' is excluded because it has a tag that is not in the list.
'user1'被排除,因为它有一个不在列表中的标记。
Hopefully I made this clear. 希望我明白这一点。 Thanks for your help!
谢谢你的帮助!
Relying on COUNT(*) = 2 will require that there can be no duplicates of user_id and name in the tags table. 依赖COUNT(*)= 2将要求在tags表中不能复制user_id和name。 If that's the case, I'd go that route.
如果是这样的话,我会走那条路。 Otherwise, this should work:
否则,这应该工作:
SELECT u.*
FROM users AS u
WHERE u.id NOT IN (
SELECT DISTINCT user_id FROM tags WHERE name NOT IN ('word1', 'word2')
) AND EXISTS (SELECT user_id FROM tags WHERE user_id = u.id)
SELECT user_id
FROM users
WHERE id IN
(
SELECT user_id
FROM tags
)
AND id NOT IN
(
SELECT user_id
FROM tags
WHERE name NOT IN ('word1', 'word2')
)
or 要么
SELECT u.*
FROM (
SELECT DISTINCT user_id
FROM tags
WHERE name IN ('word1', 'word2')
) t
JOIN users u
ON u.id = t.user_id
AND t.user_id NOT IN
(
SELECT user_id
FROM tags
WHERE name NOT IN ('word1', 'word2')
)
SELECT distinct users.id
FROM users
INNER JOIN tags ON (tags.user_id = users.id)
group by users.id
having count(*) = 2
and min(tags.name) = 'word1'
and max(tags.name) = 'word2'
To get all users that don't have a tag that is not in the list, use the query below. 要使所有没有标记的用户不在列表中,请使用以下查询。 Could be that users are returned that have no tag or only one tag matching the words, but I understand that is the desired functionality.
可能是返回的用户没有标签或只有一个标签与单词匹配,但我知道这是所需的功能。
SELECT
u.*
FROM
users u
LEFT JOIN tags t
ON t.user_id = u.userid AND
t.name NOT IN ('word1', 'word2')
WHERE
t.user_id IS NULL
SELECT u.*
FROM users u
INNER JOIN (
SELECT user_id FROM tags WHERE name IN ('word1', 'word2')
EXCEPT
SELECT user_id FROM tags WHERE name NOT IN ('word1', 'word2')
) s ON u.id = s.user_id
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.