【问题标题】:Nesting SELECT statements with duplicate entries and COUNT嵌套具有重复条目和 COUNT 的 SELECT 语句
【发布时间】:2017-03-06 13:14:03
【问题描述】:

我正在处理 3 个表:actors、films 和 actor_film。演员和电影只有 2 个字段:id(主键)和 name。 Actor_film 也有 2 个字段,actor 和 film,它们都是外键,分别代表演员和电影 ID。因此,如果一部电影中有 4 个演员,那么会有 4 个 actor_film 条目包含同一部电影和 4 个不同的演员。

我的问题是,给定某个演员的 ID,我想返回演员 ID、演员姓名、电影名称以及该电影中的演员总数。但是,我只想展示名字中包含特定字母的演员。

让我用一个例子来澄清一下。假设汤姆汉克斯只出演了两部电影,阿甘正传和拯救大兵瑞恩,我正在寻找这两部电影中名字中有“加里”或“马特”的演员。进一步假设《阿甘正传》中有 4 个演员,《拯救大兵瑞恩》中有 5 个演员。然后,我唯一想要返回的是(当然没有列名)

actor id | actor name    | film name           | # actors
abcdefg  | Gary Sinise   | Forrest Gump        | 4
hijklmn  | Matt Damon    | Saving Private Ryan | 5
opqrstu  | Paul Giamatti | Saving Private Ryan | 5 

目前,我已经完成了 75% 的使用:

SELECT actor.id, actors.name, films.name, 
FROM (
  SELECT actor_film.film 
  FROM actor_film, actors 
  WHERE actor_film.actor = actors.id
) AS a, actor_film, actors, films 
WHERE actor_film.film = a.film 
  AND actors.id = actor_film.actor 
  AND films.id = a.film;

这会返回类似的东西:

arnie | Arnold Schwarzenegger | Around the World in 80 Days
arnie | Arnold Schwarzenegger | Around the World in 80 Days

对于有 2 位演员的电影。换句话说,我无法提取电影中所有不同的演员,而是通过COUNT 隐含地而不是显式地获得正确的计数。

无论如何,我想我正在寻找某种INNER JOIN 或嵌套SELECT,但我是SQLite3 的新手,不知道如何将它们组合在一起。任何解决方案都会很棒,除此之外的任何解释也会很棒。

【问题讨论】:

    标签: sql database sqlite


    【解决方案1】:

    您不应该使用旧式连接。它们在 95 年就已经很老了,当时制定了让您更清晰地进行左连接的新标准。

    我注意到您的表格名称也使用复数形式(例如“actors”)标准样式是表格名称使用单数形式(例如“actor”)

    我使用下面的这两个建议,我也会向你展示每一步。我建议您为每个步骤运行查询并查看输出以了解一切是如何工作的,因为您是 SQL 新手。

    好的,让我们一步一步解决问题。首先要查看每个演员和他们所在的电影(您的前 3 列),这样做:

    SELECT a.id as actor_id, a.name as actor_name, f.name as film_name
    FROM actor as a
    JOIN actor_film af on a.id = af.actor
    JOIN film as f on af.film = f.id
    

    您的最后一列可以通过以下查询找到:

    SELECT af.film as film_id, count(*) as c
    FROM actor_film as af
    GROUP BY af.film
    

    现在我们把他们联合起来

    SELECT a.id as actor_id, a.name as actor_name, f.name as film_name, fc.c as num_actors
    FROM actor as a
    JOIN actor_film af on a.id = af.actor
    JOIN film as f on af.film = f.id
    JOIN (
      SELECT af.film as film_id, count(*) as c
      FROM actor_file as af
      GROUP BY af.film
    ) as fc on af.film = fc.film_id
    

    如果你愿意,你可以添加一个

    WHERE a.name = 'Gary' OR a.name = 'Matt'
    

    取决于您可能需要的平台

    WHERE lower(a.name) = 'gary' OR lower(a.name) = 'matt'
    

    【讨论】:

    • 谢谢!如果我想进一步只显示名字中包含某些字母的演员,我会把它放在哪里?在第一次 JOIN 中?
    • @ohjava -- 我为你放了几个 where 子句的例子。
    猜你喜欢
    • 2011-06-07
    • 2010-09-12
    • 1970-01-01
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-09
    相关资源
    最近更新 更多