我有一个类似于下面的表设置。
genre_id系列_id1 41 22 54 12 43 3
我想做的是能够找到所有基于所选流派组合的系列。
例如,查找类型id为1和2的所有系列。假设我想要的结果是序列ID为4。
如果我使用
SELECT series_id FROM table WHERE genre_id = 1 AND genre_id = 2
它什么也不回。
如果我使用
SELECT series_id FROM table WHERE genre_id in (1, 2)
它返回1和2中的所有内容。但是我只想要genre_id相交的行。
有办法做到这一点吗?
这应该可以做到:
SELECT series_id FROM table
WHERE genre_id IN (1, 2)
GROUP BY series_id
HAVING COUNT(*) = 2
注意,这是假设对(genre_id,series_id)是唯一的。如果不是,您将不得不将HAVING
子句更改为
HAVING COUNT(DISTINCT genre_id) = 2
还要注意,HAVING
子句中的数字2
必须与IN
子句中的项目数量相匹配。
您可以将IN()
谓词基本上看作是一系列OR
项;它相当于
SELECT series_id
FROM MyTable
WHERE genre_id = 1 OR genre_id = 2
您想要的是将OR
转换为AND
,但这没有任何意义,因为WHERE表达式一次只应用于一行genre_id不可能在同一行同时为1和2。
因此,您需要在一个表达式中比较来自两个不同行的genre_id。您可以通过连接以下两行来做到这一点:
SELECT t1.series_id
FROM MyTable AS t1
INNER JOIN MyTable AS t2 USING (series_id)
WHERE t1.genre_id = 1 AND t2.genre_id = 2
还有一个使用GROUP BY的解决方案,如另一个答案所示,但如果定义正确的索引,自联接的效率可能会高出几个数量级。
我在我的演示文稿SQL查询模式优化中描述了该解决方案的更多细节。