下面是我写的一个查询,试图找出三个演员一起出演过的所有电影:
select distinct
Movie
from
CastMember
where
Movie in (
select Movie
from CastMember
where Actor = 1
)
and Movie in (
select Movie
from CastMember
where Actor = 2
)
and Movie in (
select Movie
from CastMember
where Actor = 3
)电影和演员是电影和演员表的FKs。CastMember只有两列:电影和演员。
有更好的方法来写这个吗?
更新:仅仅使用INTERSECT的想法
select Movie
from CastMember
where Actor = 1
intersect
select Movie
from CastMember
where Actor = 2
intersect
select Movie
from CastMember
where Actor = 3发布于 2016-04-19 20:43:55
这能起作用吗?
select m.Title
from Movie m
inner join CastMember cm on cm.MovieId = m.Id
inner join Actor a on cm.ActorId = a.Id
where a.Name in ('John Travolta', 'Uma Thurman')
group by m.Title
having count(m.Id) > 1 -- this should be replaced with the number of items in the "in" list minus 1.发布于 2016-04-19 19:22:50
distinct几乎总是表明出了一些问题。
我在自欺欺人,试图看看为什么这不能产生完全相同的输出:
select Movie from CastMember where Actor in (1,2,3) -- group by Movie似乎您的模式令人困惑:很难分辨什么是FK,什么来自何处--这可能是我过度简化这里的查询的原因。
让我看看..。我不是一个超级UML迷,所以我可能搞错了,但是假设您有:

然后,您可能希望使用inner join来“链接”表--使用[FKTableName][Id]方案命名FK列,可以更容易地查看IMO的内容:
select m.Title
from Movie m
inner join CastMember cm on m.Id = cm.MovieId
inner join Actor a on a.Id = cm.ActorId
where a.Id in (1,2,3)
group by m.Title现在,上面的简单返回所有的电影演员任何一个演员曾主演-和你想要的电影,所有这些演员一起主演。
我首先使用CastMember表,并选择ActorId 1、2和3的所有行:
select MovieId, ActorId from CastMember where ActorId in (1,2,3)然后,我知道我期望每部电影有3行-假设这里是Server,我可以使用CTE和一个窗口函数来通过MovieId来划分结果,并对有3行的电影进行筛选:
with filter as (
select MovieId, row_number() over (partition by MovieId order by MovieId, ActorId) RN
from CastMember
where ActorId in (1,2,3))
select MovieId from filter where RN = 3现在我知道了我想要的Id是什么--如果我将这个select变成另一个CTE,我现在可以从Movie中选择所有行:
with filter as (
select MovieId, row_number() over (partition by MovieId order by MovieId, ActorId) RN
from CastMember
where ActorId in (1,2,3)
)
, movies as (
select MovieId from filter where RN = 3
)
select m.*
from Movie m
inner join movies on m.Id = movies.MovieId现在,我不再为乌玛·瑟曼和约翰·特拉沃塔杀死比尔:)
不幸的是,mysql不支持CTE和窗口函数(AFAIK)。同样的方法将使用不那么优雅的嵌套子查询和临时表;我将让mysql审查员想出一种更简洁的方法--无论如何,我仍然建议避免以表命名的列-- " Movie“表中的"Movie”列,意思是"Title",然后在多到多的关联表中使用"Movie“列,其中"Movie”的意思是“Movie表的主键”,当然需要修改。
https://codereview.stackexchange.com/questions/126157
复制相似问题