I have a table with data like this:
+---------+---------+
| user_id | item_id |
+---------+---------+
| 125 | 375 |
| 125 | 2 |
| 125 | 12 |
| 125 | 375 |
| 283 | 2 |
| 283 | 11 |
| 118 | 375 |
| 118 | 12 |
+---------+---------+
And I’m trying to create a query that will return all users that have ALL of the requested items, which in this case the requested items are:
item_id IN (375, 12)
So this should be the result:
+---------+
| user_id |
+---------+
| 125 |
| 118 |
+---------+
Short of joining the table to itself, I’m not really sure how I would accomplish this.
One idea I thought of was to group it by: user_id, item_id then maybe put a count on it, but that will count the double record of user_id: 125, item_id: 375 as 2, putting the total count for user_id 125 at 3, which has it’s own set of problems such as returning users that have the same item twice vs. what I really need, which is a user that has both of the requested items.
You could use
HAVING COUNT(DISTINCT item_id) = 2, but I like to be more explicit—the following approach allows for arbitrary boolean logic:See it on sqlfiddle.
This works in MySQL because it does not have true boolean types; instead, the “boolean” result of the comparisons is in fact an integer—
1if true and0if false—therefore the summation over the group is zero if no match found and non-zero otherwise: such terms can be combined with logical operators due to MySQL’s implicit type conversion back to “boolean” types. In other RDBMS, one might have to useCASE: