Project

project_id project_name
1 Crispy
2 Smile
3 Genie

Artist

artist_id artist_name
1 Lisa Simpson
2 John Smith
3 Sally Winter

Credit

credit_id credit_name
1 Producer
2 Vocalist
3 Writer
4 Mixer

Song

song_id song_name project_id
23 Hello 1
12 Goodie 3
30 Butterfly 2
55 Lollipop 1

Remix

remix_id remix_name project_id
10 Hello (Extended Mix) 1
22 Goodie (Bad Remix) 3
31 Butterfly (Sugar Remix) 2
45 Lollipop (Radio Mix) 1

Credit_To_Artist

autoid credit_id artist_id song_id remix_id
1 1 1 23 null
1 1 1 null 10
1 1 1 55 null
1 1 1 null 45
1 3 2 23 null
1 3 3 12 null
1 3 3 30 null
1 1 1 30 null
1 1 1 null 31

我想要显示一个按字母顺序的项目列表,其中显示了有多少歌曲或修复特定的艺术家计数.

The output I am wanting to achieve is this:(艺人ID=1)

artist_id project_id project_name songcount remixcount total
1 1 Crispy 2 2 4
1 2 Smile 1 1 2

哪一个查询就能实现这一结果?我已经try 了下面的查询,它可以很好地获得歌曲总数,但它不能用于混音计数,我不确定如何将这些加在一起得到总数.

提前谢谢您.

SELECT a.artist_id, p.project_id, p.project_name,
COUNT(DISTINCT c2a.song_id) as songcount, 
COUNT(DISTINCT c2a.remix_id) as remixcount 
FROM `Project` p
LEFT JOIN `Song` s ON s.project_id = p.project_id
LEFT JOIN `Remix` rm ON rm.project_id = p.project_id
LEFT JOIN `Credit_To_Artist` c2a ON c2a.song_id = s.song_id
INNER JOIN `Artist` a ON a.artist_id = c2a.artist_id
WHERE c2a.artist_id = 1
GROUP BY p.project_id
ORDER BY p.project_name ASC

推荐答案

这个问题非常微妙,因为当您有聚合和要连接的许多表时,很容易搞砸,因为第一个(错误的)冲动行为是将所有表连接在一起,然后直接将计数放在一起,这并不是进行操作的最佳方式.

以下是我会遵循的心理过程:

  • 首先,您可以考虑具有所有ID的主表,即"credit_to_artist".您注意到,歌曲和混音是在交错的唱片上找到的,我们将它们关联在一起的唯一方法是通过项目ID.
  • 因此,我们需要来自"song"表的歌曲项目ID,以及来自"remix"表的混合项目ID.我们应用相应的两个左连接.我们可以使用COALESCE(r.project_id, s.project_id)来只使用一个单独的字段来表示项目ID.
  • 然后,您注意到还需要项目名称,因此添加了一个Join操作来从"project"表中收集项目名称.

完成这些步骤后,您最终可以应用聚合,而聚合的字段是:

  • COUNT(song_id):歌曲的数量,
  • COUNT(remix_id):混音量,
  • COUNT(song_id) + COUNT(remix_id):总数

您的非聚合字段(应该包含在GROUP BY子句中)是:

  • "artist_id"
  • COALESCE(r.project_id, s.project_id),也就是统一项目ID
  • "project_name"

以下是完整的查询:

SELECT cta.artist_id,
       COALESCE(r.project_id, s.project_id)   AS project_id,
       p.project_name                         AS project_name,
       COUNT(cta.song_id)                     AS song_count,
       COUNT(cta.remix_id)                    AS remix_count,
       COUNT(cta.song_id)+COUNT(cta.remix_id) AS total
FROM      credit_to_artist cta
LEFT JOIN remix r
       ON cta.remix_id = r.remix_id
LEFT JOIN song s
       ON s.song_id = cta.song_id
INNER JOIN project p
        ON COALESCE(r.project_id, s.project_id) = p.project_id
GROUP BY cta.artist_id,
         COALESCE(r.project_id, s.project_id),
         p.project_name
ORDER BY artist_id, project_id

最后ORDER BY条完全是可选的.这只是为了可视化的目的.

Output:

artist_id project_id song_count remix_count total project_name
1 1 2 2 4 Crispy
1 2 1 1 2 Smile
2 1 1 0 1 Crispy
3 2 1 0 1 Smile
3 3 1 0 1 Genie

查看演示here.

Mysql相关问答推荐

如何获得表中只有最大值行的一个列被另一个列分区?

我需要为用户提供MySQL视图和存储的 routine ,但不是基础表

数组上的MySQL、JSON_CONTAINS用法

递归查询意外地为一个字段返回空值

带有值分隔的MySQL分组不起作用

获取连续11天未考勤的员工

在MySQL的join查询中进行计算

MySQL MDL(元数据锁)为什么会导致死锁?

时间戳上滚动窗口的 SQL 计数不同

在 where 子句中左连接多个值

更新和替换未加引号的 JSON 字符串

我在查询中没有得到正确的结果

Over() 函数不覆盖表中的所有行

如何过滤表格,以便它显示最新的数据?

MySQL 添加一个 NOT NULL 列

这是将表单数据插入 MySQL 数据库的安全方法吗?

phpmyadmin没有收到要导入的数据错误,如何解决?

MySQL嵌套 Select 查询?

如何将时刻 JS 时间插入 MySQL

NodeJS/mySQL - ER_ACCESS_DENIED_ERROR 用户'root'@'localhost'的访问被拒绝(使用密码:是)