SQL查询:统计每位艺术家的练习与演出记录总数
解决艺术家练习与演出总数统计的SQL方案
嘿,我来帮你搞定这个统计需求!你遇到的问题大概率是直接关联Practices和Shows时出现了笛卡尔积重复计数——毕竟一个艺术家的多条练习记录会和多条演出记录交叉匹配,导致统计结果虚高。下面给你两种靠谱的解决方案:
方案一:子查询预统计(推荐,性能更优)
先分别统计每个艺术家的练习数和演出数,再和Artists表关联,从根源避免重复:
SELECT a.Artist_ID, a.Name, -- 假设Artists表有Name字段,可根据实际表结构调整 COALESCE(p.Practice_Count, 0) AS Total_Practices, COALESCE(s.Show_Count, 0) AS Total_Shows FROM Artists a LEFT JOIN ( -- 子查询统计每位艺术家的练习总数 SELECT Artist_ID, COUNT(*) AS Practice_Count FROM Practices GROUP BY Artist_ID ) p ON a.Artist_ID = p.Artist_ID LEFT JOIN ( -- 子查询统计每位艺术家的演出总数 SELECT Artist_ID, COUNT(*) AS Show_Count FROM Shows GROUP BY Artist_ID ) s ON a.Artist_ID = s.Artist_ID;
关键细节说明:
- 使用
LEFT JOIN确保所有艺术家都能出现在结果中,哪怕他们没有练习或演出记录 COALESCE()函数把NULL转换成0,避免没有记录时显示空白值- 子查询先分组统计再关联,数据量更小,在大表场景下性能远优于直接关联后去重
方案二:DISTINCT去重统计(适合小表场景)
如果你的数据量不大,也可以直接关联三张表,用COUNT(DISTINCT)去重避免重复计数:
SELECT a.Artist_ID, a.Name, COUNT(DISTINCT p.Practice_ID) AS Total_Practices, COUNT(DISTINCT s.Show_ID) AS Total_Shows FROM Artists a LEFT JOIN Practices p ON a.Artist_ID = p.Artist_ID LEFT JOIN Shows s ON a.Artist_ID = s.Artist_ID GROUP BY a.Artist_ID, a.Name;
注意点:
- 必须用
COUNT(DISTINCT 自增ID),而不是直接COUNT(*),否则会因为笛卡尔积产生的重复行导致统计错误 - 这种方式在数据量大时,关联后的临时表会非常大,性能不如方案一
你可以根据自己的表数据规模选择合适的方案,测试一下应该就能得到正确的统计结果啦!
内容的提问来源于stack exchange,提问作者user3498517
相关产品推荐
相关产品推荐

