SQL 寻找相似之处

SQL Finding similarities

“判断是否有同名演员出现在同一部电影中。”

这是我的任务,我应该用子查询来完成它,但我真的不知道还能做什么。我尝试了所有分组依据、排序依据和计数,但我只是没有达到我在同一部电影中获得相同名字演员的地步。

也许有人可以帮助我?我正在使用 Sakila 数据库

    SELECT 
a.first_name
,(a.last_name)
,a.actor_id
, f.title
FROM actor a 

JOIN film_actor fa ON fa.actor_id = a.actor_id
JOIN film f ON f.film_id = fa.film_id

JOIN(SELECT b.first_name, COUNT(*)
     FROM actor B
     GROUP BY b.first_name
     HAVING COUNT(*) > 1 ) b 
     ON a.first_name = b.first_name
     
     GROUP BY a.last_name
     HAVING COUNT(f.title) > 1
     
     
     
     ORDER BY a.first_name

这个怎么样:

SELECT f.title, f.film_id, a.first_name, a.last_name, a.actor_id
FROM actor a 
JOIN film_actor fa ON fa.actor_id = a.actor_id
JOIN film f ON f.film_id = fa.film_id
WHERE a.first_name IN (
         SELECT a2.first_name
         FROM actor a2
         JOIN film_actor fa2 ON fa2.actor_id = a2.actor_id
         JOIN film f2 ON f2.film_id = fa2.film_id
         WHERE a2.actor_id <> a.actor_id AND f2.film_id = f.film_id
)
ORDER BY f.title ASC, a.last_name ASC, a.first_name ASC

逐步解释查询

SELECT 连接表中的所需字段

JOIN 必要的表格

WHERE(这里是子查询)a.first_name在集合中:

演员的名字,与当前演员的名字不同 (a2.actor_id <> a.actor_id) 而电影相同 (f2.film_id = f.film_id)

where 中的子查询与 select 类似,将连接查询作为父查询。

PS:

可以对这个基本查询模板进行变体:

  1. 例如 film_id 可以作为参数给出,因此可以找到特定电影的所有同名演员。
  2. 还可以 groupcount 同一部电影中有多少同名演员出现,例如按 film_id 分组并计数。
  3. 甚至可以通过删除不必要的连接来优化查询(例如 film.title 可能根本不需要)等等..

返回单个结果(而不是元组或聚合)的优点是同一部电影中同名演员的数量不固定,并且可以操纵结果,例如通过分组和计数或获取每个演员的更多信息, 更容易。

价格稍微复杂一些,查询速度可能较慢。

您只能使用联接来执行此操作:

select f.title, a1.first_name, a1.last_name as last_name_1, a2.last_name as last_name_2
from film f
inner join film_actor fa1 on fa1.film_id = f.film_id
inner join film_actor fa2 on fa2.film_id = f.film_id
inner join actor a1 on a1.actor_id = fa.actor_id
inner join actor a2 on a2.actor_id = fa.actor_id
where a1.first_name = a2.first_name and a1.actor_id < a2.actor_id

film table 开始,这遵循 actorfilm_actor 两次的关系,然后过滤具有相同名字的不同演员。

因此,您会得到具有相同姓氏并在同一部电影中演出的演员的元组。不等式条件确保没有“镜像”记录(即每个元组每部电影只出现一次)。

我会简单地使用聚合:

SELECT fa.film_id, a.first_name,
       GROUP_CONCAT(a.last_name) as last_names,
       GROUP_CONCAT(a.actor_id) as actor_ids
FROM actor a JOIN
     film_actor fa
     ON fa.actor_id = a.actor_id
GROUP BY fa.film_id, a.first_name
HAVING COUNT(*) > 1;

您的问题没有指定结果集应该是什么样子。这 returns 每个演员在电影中具有相同名字的一行。姓氏与演员 ID 一样连接成一个字符串。