简体   繁体   中英

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.

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.

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.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM