MySQL ONLY IN()等效子句

时间:2013-05-09 12:23:39

标签: mysql clause relational-division

我在这里给出了一个非常抽象的问题版本,所以请耐心等待。我有一个查询,将检查特定的主体是否具有相同类型的某些多个参数。例如,就巧克力而言,男孩有多种选择。但是,我想从桌子上选择那些我提到的巧克力的男孩。不仅不是更少,也不是'喜欢'或不'IN()'。

SELECT boy_id from boys_chocolates WHERE chocolate_id ONLY IN('$string');

..当然'$ string'是一个PHP变量,其中包含逗号分隔值,只包含那些我想用来吸引男孩的巧克力。

我知道这是无效的MySQL语句,但有没有与此有效的对应?

编辑:

这是更全面的查询,它在特殊情况下获取记录,但并非总是如此。

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   |
+----+--------------+---------+

当我单独选择1000来拉动两个男孩(或)1000和1003以取出身份证10007的男孩时,没有任何事情发生。

1 个答案:

答案 0 :(得分:10)

此问题称为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

示例:

SELECT boy_id 
FROM   boys_chocolates 
WHERE  chocolate_id IN (1,2,3,4)
GROUP  BY boy_id 
HAVING COUNT(DISTINCT chocolate_id) = 4

但是,如果chocolate_id对于每个boy_id都是唯一的,则DISTINCT关键字是可选的。

SELECT boy_id 
FROM   boys_chocolates 
WHERE  chocolate_id IN (1,2,3,4)
GROUP  BY boy_id 
HAVING COUNT(*) = 4

更新1

...我想从桌子上选择那些我提到的巧克力的男孩。不多也不少......

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