子查询对项目进行计数,然后按主查询的字段对它们进行分组,不重复

Subquery to count items, and then group them by a field of the main query without duplicates

我想统计 "child" 在 N..N 关系中出现的次数,并按 "parent" 的字段对结果进行分组。


我很难用确切的词来表达这一点,所以假设我有 3 tables:MovieActor, Play, 其中 PlayMovie 之间的关系演员。演员可以在电影中表演。 可能有些演员存在于数据库中,但从未在数据库的任何电影中扮演过。

电影table中,我有一个类型

我想计算每个类型扮演过的演员的数量,而不是每个类型多次计算同一个演员。


我目前在每部戏 actor_id 上使用 DISTINCT,这意味着理论上在同一部电影中多次出演的演员将出现一次......但这是一个没有意义的场景(因为演员在 Play table) 中每部电影只会出现一次,所以它没有用,也不是我想要的。有更好的主意吗?

我想将所有内容都保存在一个查询中,因为我实际上正在执行其他子查询以获得每个流派的其他统计信息。

这是我的查询的样子,没有其他子查询:

SELECT
    movie.genre,

    SUM(
        SELECT COUNT(DISTINCT play.actor_id)
        FROM play
        WHERE play.movie_id = movie.id
    ) AS number_of_actors

    FROM movie

    GROUP BY movie.genre

目前,如果一个演员演过几部电影,就会被计算多次。

只需根据各自的关系在各种表之间做一个简单的 INNER JOIN,然后在一组 genre 上使用 COUNT(DISTINCT ..),以获得每个流派的独特演员:

SELECT 
  m.genre, 
  COUNT(DISTINCT p.actor_id) AS number_of_actors 
FROM movie AS m 
JOIN play AS p ON p.movie_id = m.id 
GROUP BY m.genre

你的问题是你无法在求和的每个元素之间进行不同的通信,所以你最终会得到重复的值。写成 JOIN 更简单。我使用 LEFT JOIN 以防电影在 play table 中没有条目,在这种情况下 COUNT 将为 0。

SELECT m.genre
       COALESCE(COUNT(DISTINCT p.actor_id), 0) AS number_of_actors
FROM movie m
LEFT JOIN play p ON p.movie_id = m.id
GROUP BY m.genre