返回与所有请求项匹配的结果

时间:2012-12-13 23:17:23

标签: mysql

我有一个包含这样数据的表:

+---------+---------+
| user_id | item_id |
+---------+---------+
|     125 |     375 |
|     125 |       2 |
|     125 |      12 |
|     125 |     375 |
|     283 |       2 |
|     283 |      11 |
|     118 |     375 |
|     118 |      12 |
+---------+---------+

我正在尝试创建一个查询,该查询将返回包含所有请求项目的所有用户,在这种情况下,请求的项目为:

item_id IN (375, 12) 

所以这应该是结果:

+---------+
| user_id |
+---------+
|     125 |
|     118 |
+---------+

没有加入桌子本身,我不确定如何实现这一目标。 我想到的一个想法是将它分组:user_id, item_id然后可能会对它进行计数,但这会将user_id: 125, item_id: 375的双记录计为2,将user_id 125的总计数设为3,它有自己的一组问题,例如返回具有相同项目两次的用户与我真正需要的项目,这是一个拥有两个请求项目的用户。

1 个答案:

答案 0 :(得分:1)

您可以使用HAVING COUNT(DISTINCT item_id) = 2,但我希望更明确 - 以下方法允许任意布尔逻辑:

SELECT   user_id
FROM     my_table
WHERE    item_id IN (375, 12)
GROUP BY user_id
HAVING   SUM(item_id = 375) AND SUM(item_id = 12)

sqlfiddle上查看。

这适用于MySQL,因为它没有真正的布尔类型;相反,比较的“布尔”结果实际上是一个整数 - 1如果为真,0如果为假 - 因此如果没有找到匹配则该组的总和为零,否则为非零:由于MySQL的隐式类型转换回“布尔”类型,这些术语可以与逻辑运算符组合。在其他RDBMS中,可能必须使用CASE

HAVING   SUM(CASE WHEN item_id = 375 THEN 1 ELSE 0 END) > 0
     AND SUM(CASE WHEN item_id =  12 THEN 1 ELSE 0 END) > 0