vtolentino
vtolentino

Reputation: 784

MYSQL many-to-many selection with AND condition

I found a similar question in stackoverflow, but it is not quite the problem I am facing right now. I could not find a better way of describing the required query, than the following:

Select all the entries which have at least the property one AND property two AND ...

Consider the following tables:

users

|  id  |  name  |
+------+--------+
|  1   |  john  |
+------+--------+
|  2   |  liu   |
+------+--------+  

sports

|  id  |  user_id  |    sport   |
+------+-----------+------------+
|  1   |     1     |    swim    |
+------+-----------+------------+
|  2   |     1     |    run     |
+------+-----------+------------+
|  3   |     1     |  football  |
+------+-----------+------------+
|  4   |     1     |   volley   |
+------+-----------+------------+
|  5   |     2     |    swim    |
+------+-----------+------------+
|  6   |     2     |    run     |
+------+-----------+------------+

I would like to be able to make the following queries:

  1. Select all users who only swim (straight forward)

Returns:

|  id  |  name  |
+------+--------+
|  1   |  john  |
+------+--------+
|  2   |  liu   |
+------+--------+
  1. Select all users who can swim AND run

Returns:

|  id  |  name  |
+------+--------+
|  1   |  john  |
+------+--------+
|  2   |  liu   |
+------+--------+
  1. Select all users who can swim AND run AND play football

Returns:

|  id  |  name  |
+------+--------+
|  1   |  john  |
+------+--------+

The number of sports should be dynamic.

Thank you.

Upvotes: 1

Views: 32

Answers (2)

Uueerdo
Uueerdo

Reputation: 15961

The number of items in the list can't really be "dynamic", at least not any more than any list of values can be.

SELECT u.id, u.name
FROM users AS u
INNER JOIN sports AS s ON s.user_id = u.id
WHERE s.sport IN ('football','run','swim')
GROUP B u.id, u.name
HAVING COUNT(DISTINCT sport) = 3
;

For longer/shorter lists, you just need to adjust the 3 accordingly.

Upvotes: 2

juergen d
juergen d

Reputation: 204854

To check for all 3 you can do

select u.id, u.name
from users u
join sports s on s.user_id = u.id
group by u.id, u.name
having sum(sport = 'swim') > 0
   and sum(sport = 'run') > 0
   and sum(sport = 'football') > 0

Remove the ones from the query that you don't need for the other selects.

Upvotes: 1

Related Questions