使用LEFT JOIN与INNER JOIN关联三表:获取经理、收益及唯一艺人
解决经理收益统计+关联不重复艺人并支持艺人ID搜索的问题
看起来你已经搞定了经理收益总和的查询,现在要扩展成包含不重复艺人列表,还能按艺人ID搜索对吧?我来帮你调整SQL语句,满足所有需求:
首先,我们需要在子查询里同时计算总收益和聚合不重复的艺人,还要保证即使没有演出的经理也能被保留(用LEFT JOIN)。这里用GROUP_CONCAT(DISTINCT ...)来生成不重复的艺人列表,非常适合这种场景。
基础版本:获取所有经理的收益+关联不重复艺人
SELECT a.id AS manager_id, a.name AS manager_name, IFNULL(b.total_earning, 0) AS total_earning, IFNULL(b.unique_artists, '') AS unique_artists FROM managersTbl a LEFT JOIN ( SELECT g.manager AS manager_id, SUM(g.earning) AS total_earning, -- 用GROUP_CONCAT拼接不重复的艺人姓名,逗号分隔 GROUP_CONCAT(DISTINCT ar.name SEPARATOR ', ') AS unique_artists FROM gigsTbl g -- 用LEFT JOIN避免因gigs中艺人ID不存在于artistsTbl而丢失数据 LEFT JOIN artistsTbl ar ON g.artist = ar.id GROUP BY g.manager ) b ON a.id = b.manager_id;
这个查询会输出:
- 经理ID、姓名
- 总收益(没有演出的显示0)
- 该经理负责的所有不重复艺人姓名,用逗号分隔
支持按艺人ID搜索的版本
如果要搜索特定艺人ID(比如艺人ID=1),我们可以通过HAVING子句筛选出至少负责过该艺人的经理,同时保留他们的全部收益和艺人列表:
SELECT a.id AS manager_id, a.name AS manager_name, IFNULL(b.total_earning, 0) AS total_earning, IFNULL(b.unique_artists, '') AS unique_artists FROM managersTbl a LEFT JOIN ( SELECT g.manager AS manager_id, SUM(g.earning) AS total_earning, GROUP_CONCAT(DISTINCT ar.name SEPARATOR ', ') AS unique_artists FROM gigsTbl g LEFT JOIN artistsTbl ar ON g.artist = ar.id GROUP BY g.manager -- 筛选出至少有一次该艺人演出的经理 HAVING SUM(CASE WHEN g.artist = 1 THEN 1 ELSE 0 END) > 0 ) b ON a.id = b.manager_id -- 只显示符合搜索条件的经理 WHERE b.manager_id IS NOT NULL;
如果你只想统计该艺人相关的收益(而不是经理的全部收益),可以把WHERE g.artist = 1加到子查询的GROUP BY之前:
SELECT a.id AS manager_id, a.name AS manager_name, IFNULL(b.total_earning, 0) AS total_earning, IFNULL(b.unique_artists, '') AS unique_artists FROM managersTbl a LEFT JOIN ( SELECT g.manager AS manager_id, SUM(g.earning) AS total_earning, GROUP_CONCAT(DISTINCT ar.name SEPARATOR ', ') AS unique_artists FROM gigsTbl g LEFT JOIN artistsTbl ar ON g.artist = ar.id WHERE g.artist = 1 -- 只统计该艺人的演出 GROUP BY g.manager ) b ON a.id = b.manager_id WHERE b.manager_id IS NOT NULL;
说说你之前尝试的SQL问题
你之前的子查询里用了INNER JOIN artistsTbl,这会导致如果gigsTbl里的艺人ID在artistsTbl中不存在时,对应的演出收益会被排除,用LEFT JOIN更稳妥。另外,原查询没有把艺人信息聚合到结果里,所以看不到对应的艺人列表~
内容的提问来源于stack exchange,提问作者Hannah May
相关产品推荐
相关产品推荐

