MySQL统计含组合艺人的独立艺人对应歌曲数量问题
解决组合艺人的歌曲统计问题
要实现你期望的统计结果,核心是拆分组合中的独立艺人,并确保只统计有solo作品的艺人。下面分步骤给出基于正则表达式的解决方案:
思路概述
- 先去重原表的重复行,避免同一歌曲被多次统计;
- 用正则拆分组合字段中的每个独立艺人,将每个艺人与对应的歌曲关联;
- 统计每个艺人的不重复歌曲数量;
- 过滤掉没有solo作品的艺人(即从未以单独身份出现在
artist字段中的艺人)。
PostgreSQL 实现代码
WITH unique_songs AS ( -- 第一步:去重原表的重复行,得到唯一的(艺人/组合,歌曲)对 SELECT DISTINCT artist, title FROM list ), split_artists AS ( -- 第二步:用正则拆分组合中的艺人,每个艺人单独关联歌曲 SELECT REGEXP_SPLIT_TO_TABLE(artist, ' & ') AS individual_artist, title FROM unique_songs ), artist_song_counts AS ( -- 第三步:统计每个艺人的不重复歌曲数 SELECT individual_artist AS artist, COUNT(DISTINCT title) AS total FROM split_artists GROUP BY individual_artist ), solo_artists AS ( -- 第四步:筛选有solo作品的艺人(用正则匹配无&的字段) SELECT DISTINCT artist FROM list WHERE artist NOT REGEXP ' & ' ) -- 关联统计结果和solo艺人列表,得到最终结果 SELECT asc.artist, asc.total FROM artist_song_counts asc JOIN solo_artists sa ON asc.artist = sa.artist ORDER BY asc.total DESC;
执行后会得到你期望的结果:
artist total Lady GaGa 3 Beyoncé 2 Rihanna 2
MySQL 实现代码(适配无原生拆分函数的数据库)
如果使用MySQL,没有REGEXP_SPLIT_TO_TABLE函数,可以用递归CTE结合正则拆分:
WITH RECURSIVE unique_songs AS ( SELECT DISTINCT artist, title FROM list ), split_artists AS ( -- 初始化:拆分第一个艺人 SELECT artist, title, 1 AS pos, REGEXP_SUBSTR(artist, '[^&]+', 1, 1) AS individual_artist FROM unique_songs UNION ALL -- 递归:拆分后续的艺人,直到没有更多结果 SELECT artist, title, pos + 1, REGEXP_SUBSTR(artist, '[^&]+', 1, pos + 1) AS individual_artist FROM split_artists WHERE REGEXP_SUBSTR(artist, '[^&]+', 1, pos + 1) IS NOT NULL ), trimmed_artists AS ( -- 去除艺人名称前后的空格(拆分后可能带空格) SELECT TRIM(individual_artist) AS artist, title FROM split_artists ), artist_song_counts AS ( SELECT artist, COUNT(DISTINCT title) AS total FROM trimmed_artists GROUP BY artist ), solo_artists AS ( SELECT DISTINCT artist FROM list WHERE artist NOT REGEXP ' & ' ) SELECT asc.artist, asc.total FROM artist_song_counts asc JOIN solo_artists sa ON asc.artist = sa.artist ORDER BY asc.total DESC;
关键细节说明
- 正则
' & '用于匹配组合中的分隔符,确保准确拆分每个艺人; COUNT(DISTINCT title)保证同一歌曲不会因为艺人多次参与(比如solo+组合)被重复统计;NOT REGEXP ' & '用于筛选solo艺人,完全符合你要求用REGEXP运算符的需求。
内容的提问来源于stack exchange,提问作者kuznikowski
相关产品推荐
相关产品推荐

