问题
I am giving a very abstract version of my question here, so please bear with me. I have a query that will check whether a particular body has certain multiple parameters of same type. Example, a boy has multiple selection as far as chocolates are concerned. But, I want to choose boys from the table who have exactly the chocolates I mention. Not more not less and not 'LIKE' or not 'IN()'.
SELECT boy_id from boys_chocolates WHERE chocolate_id ONLY IN('$string');
..where of course '$string' is a PHP variable containing comma separated values of only those chocolates I want to use to pull the boys.
I know this is invalid MySQL statement, but is there any valid equivalent to this?
EDIT:
This is more comprehensive query which gets records in special cases, but not always.
SELECT boys.* FROM schools_boys INNER JOIN boys ON boys.boy_id=schools_boys.boy_id
INNER JOIN chocolates_boys a ON a.boy_id=boys.boy_id INNER JOIN schools
ON schools.school_id=schools_boys.school_id WHERE a.chocolate_id IN(1000,1003)
AND
EXISTS
(
SELECT 1
FROM chocolates_boys b
WHERE a.boy_id=b.boy_id
GROUP BY boy_id
HAVING COUNT(DISTINCT chocolate_id) = '2'
)
GROUP BY schools_boys.boy_id HAVING COUNT(*) = '2'
Boys Table
+--------+-------------+
| id | boy |
+--------+-------------+
| 10007 | Boy1 |
| 10008 | Boy2 |
| 10009 | Boy3 |
+--------+-------------+
Chocolates Boys Table
+----+---------+--------------+
| id | chocolate_id | boy_id |
+----+--------------+---------+
| 1 | 1000 | 10007 |
| 2 | 1003 | 10007 |
| 3 | 1006 | 10007 |
| 4 | 1000 | 10009 |
| 5 | 1001 | 10009 |
| 6 | 1005 | 10009 |
+----+--------------+---------+
Nothing happens when I select 1000 alone to pull two boys (or) 1000 and 1003 to pull out the boy with ID 10007.
回答1:
this problem is called Relational Division
SELECT boy_id
FROM boys_chocolates
WHERE chocolate_id IN ('$string')
GROUP BY boy_id
HAVING COUNT(DISTINCT chocolate_id) = ? -- <<== number of chocolates specified
example:
SELECT boy_id
FROM boys_chocolates
WHERE chocolate_id IN (1,2,3,4)
GROUP BY boy_id
HAVING COUNT(DISTINCT chocolate_id) = 4
- SQL of Relational Division
however, if the chocolate_id
is unique for every boy_id
, DISTINCT
keyword is optional.
SELECT boy_id
FROM boys_chocolates
WHERE chocolate_id IN (1,2,3,4)
GROUP BY boy_id
HAVING COUNT(*) = 4
UPDATE 1
...I want to choose boys from the table who have exactly the chocolates I mention. Not more not less...
SELECT boy_id
FROM boys_chocolates a
WHERE chocolate_id IN (1,2,3,4) AND
EXISTS
(
SELECT 1
FROM boys_chocolates b
WHERE a.boy_ID = b.boy_ID
GROUP BY boy_id
HAVING COUNT(DISTINCT chocolate_id) = 4
)
GROUP BY boy_id
HAVING COUNT(*) = 4
- SQLFiddle Demo
来源:https://stackoverflow.com/questions/16461707/mysql-only-in-equivalent-clause