具有多个条件的SQL WHERE语句

问题描述

我有一个电影,片名,人物和角色表(如下),我想找到既是演员又是导演的人的名字。

电影(表格)

id int
title

积分(表格)

id int
movie_id int
person_id int
role_id int

people(TABLE)

id int
name

角色(表格)

id int
role    (Actor,Director)

这就是我所做的:

SELECT p.name,r.role,m.role_id
FROM mtm_credits m
JOIN people p ON p.id = m.person_id
JOIN roles r ON r.id = m.role_id
WHERE role = 'Director' AND role = 'Actor';

但是,我得到0条结果。任何建议表示赞赏。

解决方法

问题在于结果表中没有一行“角色”既是“导演”又是“演员”的行,因为“角色”只能是一个值。

在联接后首先考虑表的外观很有用。在这种情况下,您可以:

credits.id,credits.movie_id,credits.person_id,credits.role_id,person.id,person.name,role.id,role.name

现在既是导演又是演员的人在此表中将有两行,如下所示:

| credits.id | credits.movie_id | credits.person_id | credits.role_id | person.id | person.name | role.id | role.name |
| 111 | 222 | 333 | 444 | 555 | 333 | N. Cage | 555 | Actor |
| 111 | 222 | 333 | 444 | 555 | 333 | N. Cage | 555 | Director |

正如其他人所说,您需要执行聚合,以便一行可以具有多个角色值,或者您可以获取结果并在外部进行过滤

,

我认为您想要汇总:

SELECT p.name
FROM mtm_credits m JOIN
     people p
     ON p.id = m.person_id JOIN
     roles r
     ON r.id = m.role_id
WHERE r.role IN ('Director','Actor')
HAVING COUNT(DISTINCT r.role) = 2;
,

查询的问题是您要搜索一个既是导演又是演员的角色:两个条件不能同时满足,因此查询为空。

每当您需要查看多行时,就会想到聚合:

SELECT p.*
FROM mtm_credits m
JOIN people p ON p.id = m.person_id
JOIN roles r ON r.id = m.role_id
WHERE r.role IN ('Director','Actor')
GROUP BY p.id
HAVING COUNT(DISTINCT r.role) = 2

这会搜索作为导演演员的人员,然后按人员对行进行分组;最后,having子句只允许同时担任这两种角色的人。

,

有两个答案使用相同的方法,但是都错了。如果这个假设的数据库每人只包含一部电影,那么它将成功。如果有多个电影引用了people记录,或者如果people引用了一个credits记录,而roles的{​​{1}}记录中又加入了{。 {1}} ='导演'或rolesrole ='演员',此查询返回该无效结果的记录。这会破坏指定的行为。

请注意,@ Jason-Chen解释了您在查询中遇到的问题,而我在发布时给出的解决方案特别矛盾了这两个答案。

管理员不应该简单地计算结果以确保每个人具有多个角色,这是上述两个示例唯一的保证,管理员应该查询所有角色记录列表中都存在的连接,其中“导演”是roles.role值,以及所有记录,其中“演员”是roles.role值。

请注意,我在下面使用了不同的名称,因为我通常会发现单字母别名的做法很糟糕,我希望教师能为新生提供更好的做法。此外,我发现单数形式的表名产生的代码可读性最高。

roles

我正在从角色表的两个子查询中选择一个值,该值不需要别名,而是表现为一个集合。只要使用的键在连接的两面都建立索引,即使对于相当大的表,也可以非常快速地进行查找。

此外,这比联接更好,因为给定现实生活中的示例,例如“基努·里夫斯”,“梅尔·吉布森”,“汤姆·克鲁斯”或其他名人,其中很多导演/演员电影都在他们的指挥之下,每条这样的记录将导致结果集放大,其中在数据中添加一条记录会导致多个结果记录。