I have an inner join like this:
SELECT
p.id
, p.date
, pu.user_id
FROM projections p
INNER JOIN projection_user AS pu ON p.id = pu.projection_id
WHERE pu.user_id IN ('1', '3')
This returns the following results:
id | date | user_id
--------------------------
16 | 2020-03-05 | 1
17 | 2020-03-05 | 1
17 | 2020-03-05 | 3
I would like to only return rows where the projection ( p.id
) has the exact pu.user_id
values supplied in my WHERE
clause -- in this case the projection with a p.id
of 17, since it has both pu.user_id
1 and 3, and no others. In the full code I am actually grouping by p.id
for the final result:
SELECT
p.id
, p.date
FROM projections p
INNER JOIN projection_user AS pu ON p.id = pu.projection_id
WHERE pu.user_id IN ('1', '3')
GROUP BY p.id
id | date
--------------------------
16 | 2020-03-05
17 | 2020-03-05
How can I only return the projection with p.id
of 17?
Use aggregation:
SELECT p.id, p.date, GROUP_CONCAT(pu.user_id)
FROM projections p INNER JOIN
projection_user pu
ON p.id = pu.projection_id
GROUP BY p.id, p.date
HAVING SUM(pu.user_id IN (1, 3)) = COUNT(*) AND
COUNT(*) = 2;
Note: This assumes no duplicates in projection_user
, which is typically a reasonable assumption. The query can be tweaked if such duplicates are possible.
Or, if you prefer:
SELECT p.id, p.date,
GROUP_CONCAT(pu.user_id ORDER BY pu.user_id) as user_ids
FROM projections p INNER JOIN
projection_user pu
ON p.id = pu.projection_id
GROUP BY p.id, p.date
HAVING user_ids = '1,3';
This amendment to Gordon Linoff's answer works as needed:
SELECT
p.id
, p.date
FROM projections p
INNER JOIN projection_user AS pu ON p.id = pu.projection_id
GROUP BY p.id
HAVING SUM(pu.user_id IN (1, 3)) = COUNT(*) AND COUNT(*) = 2
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.