如何在一个 mysql 查询中 return 所有关系数据,并在按关系查询时仅停止连接一个结果

How can I return all relationship data in one mysql query and stop only one result being concatanated when querying by relationship

我正在尝试执行一个 MYSQL 查询,该查询检索关系数据并将其连接到 json 个对象的串联字符串中,稍后我 json_decode.

我设置了 fiddle here 但是 JSON_OBJECT 不起作用。架构在 markdown table.

中或下方

我想要达到的最终结果是下面table中的结果。

id title date_published artists genres
1 My Song 2022-01-01 15:00:01 [{id: 1, name: 'Pauli', is_featuring: 0}, {id: 2, name: 'Tony', is_featuring: 1}] [{id: 1, name: 'Rock'}, {id: 2, name: 'Pop'}]

下面是使用艺术家 ID 根据艺术家检索歌曲的查询。我得到了一个歌曲列表,但如果歌曲中有不止一位艺术家,它只会 returns 其 ID 传递给 sql 查询的艺术家。

尝试按流派进行查询时会发生类似的情况。

所以我的问题是如何在结果中 return 我想要的数据,同时对艺术家或流派执行查询?我还必须获得查询结果总数的总记录数 return.

SELECT ms.id, ms.title, ms.date_published, 
CONCAT('[', GROUP_CONCAT(DISTINCT(JSON_OBJECT('id', ma.id, 'name', ma.name, 'is_featuring', mas.is_featuring_artist)) ORDER BY mas.id separator ','), ']') AS artists, 
CONCAT('[', IF(mg.id IS NULL, '', GROUP_CONCAT(DISTINCT(JSON_OBJECT('id', mg.id, 'name', mg.name)) ORDER BY mg.name separator ',')), ']') AS genres 
FROM songs ms 
LEFT JOIN artist_song mas ON mas.song_id = ms.id 
LEFT JOIN artists ma ON ma.id = mas.artist_id 
LEFT JOIN genre_song mgs ON mgs.song_id = ms.id 
LEFT JOIN genres mg ON mg.id = mgs.genre_id 
WHERE ma.id = 2 AND ms.published = 1 
GROUP BY ms.id
ORDER BY ms.date_published DESC 
LIMIT 10  
OFFSET 0;

这是我要返回的结果。当我查询 id 为 2 的艺术家时,请注意艺术家 Pauli 如何不再出现在艺术家数组中。

id title date_published artists genres
1 My Song 2022-01-01 15:00:01 [{id: 2, name: 'Tony', is_featuring: 1}] [{id: 1, name: 'Rock'}, {id: 2, name: 'Pop'}]

下面是tables

歌曲Table

id name published

艺术家Table

id name

艺术家歌曲Table

id artist_id song_id is_featured

流派Table

id name

流派歌曲Table

id genre_id song_id

您需要加入 artist_song 两次。一种是限制被选中的歌曲,另一种是获取歌曲中所有的歌手。

SELECT ms.id, ms.title, ms.date_published, 
CONCAT('[', GROUP_CONCAT(DISTINCT(JSON_OBJECT('id', ma.id, 'name', ma.name, 'is_featuring', mas.is_featuring_artist)) ORDER BY mas.id separator ','), ']') AS artists, 
CONCAT('[', IF(mg.id IS NULL, '', GROUP_CONCAT(DISTINCT(JSON_OBJECT('id', mg.id, 'name', mg.name)) ORDER BY mg.name separator ',')), ']') AS genres 
FROM songs ms 
JOIN artist_song mas1 ON mas1.song_id = ms.id
JOIN artist_song mas ON mas.song_id = ms.id 
JOIN artists ma ON ma.id = mas.artist_id 
LEFT JOIN genre_song mgs ON mgs.song_id = ms.id 
LEFT JOIN genres mg ON mg.id = mgs.genre_id 
WHERE mas1.artist_id = 2 AND ms.published = 1 
GROUP BY ms.id
ORDER BY ms.date_published DESC 
LIMIT 10  
OFFSET 0;

没有必要加入 artists 两次,因为你在限制时没有使用 table 中的任何东西。您可以将艺术家 ID 限制为 mas1.artist_id.