如何解决这个关系划分查询?

Posted

技术标签:

【中文标题】如何解决这个关系划分查询?【英文标题】:How to solve this relational division query? 【发布时间】:2013-05-29 01:05:59 【问题描述】:

我有一个表 (movies) 有两个外键 (movie_id, genre_id)。当然,这两个字段都不是唯一的。

如何选择具有两种或多种特定类型的电影?

我想做这样的事情:

SELECT movie_id 
FROM movies
WHERE genre_id = 1 AND genre_id = 2 AND genre_id = 3

【问题讨论】:

【参考方案1】:

这是一个Relational Division 问题。

SELECT movie_id 
FROM   movies
WHERE  genre_id IN (1, 2, 3)   -- <<== list of genre_id
GROUP  BY movie_id
HAVING COUNT(*) = 3            -- <<== count of genre_id
SQL of Relational Division

如果每个movie_idgenre_id 不是唯一的,则需要一个DISTINCT 关键字来过滤唯一的。

SELECT movie_id 
FROM   movies
WHERE  genre_id IN (1, 2, 3)             -- <<== list of genre_id
GROUP  BY movie_id
HAVING COUNT(DISTINCT genre_id) = 3      -- <<== count of genre_id

【讨论】:

真的很感谢大家,效果很好。我不知道如何解决它 @JW웃 您能否详细解释一下“拥有 count(*) = 3”是如何工作的?如果只有 2 个genre_ids 怎么办? 5?您会分别将 have count 子句更改为 = 2 或 5 吗?我还注意到,如果我没有 have count 子句,那么 where in 子句就像每个 ID 的常规 OR 子句一样。【参考方案2】:

这是“set-within-sets”查询的示例。我认为最通用的方法是将所有条件放在having 子句中:

SELECT movie_id
FROM movies
group by movie_id
having sum(case when genre_id = 1 then 1 else 0 end) > 0 and
       sum(case when genre_id = 2 then 1 else 0 end) > 0 and
       sum(case when genre_id = 3 then 1 else 0 end) > 0;

having 子句中的每个子句都在计算与每种类型匹配的记录数。

【讨论】:

以上是关于如何解决这个关系划分查询?的主要内容,如果未能解决你的问题,请参考以下文章

如何解决这个递归关系:T(n) = 4*T(sqrt(n)) + n

如何在熊猫数据框中划分时间

如何在春季配置多对一和一对多关系? Hibernate会无限调用同一查询

地图区域划分转换成数学模型解决问题

活动记录查询以获取关系[重复]

MySQL查询多对多关系:联合?