Lem*_*m0n 9 mysql join group-by group-concat
我有一个"歌曲","Songs_Tags"(与歌曲相关的歌曲)和"Songs_Votes"(与布尔喜欢/不喜欢的歌曲相关)的表格.
我需要使用其标签的GROUP_CONCAT()以及喜欢(真实)和不喜欢(假)的数量来检索歌曲.
我的查询是这样的:
SELECT
s.*,
GROUP_CONCAT(st.id_tag) AS tags_ids,
COUNT(CASE WHEN v.vote=1 THEN 1 ELSE NULL END) as votesUp,
COUNT(CASE WHEN v.vote=0 THEN 1 ELSE NULL END) as votesDown,
FROM Songs s
LEFT JOIN Songs_Tags st ON (s.id = st.id_song)
LEFT JOIN Votes v ON (s.id=v.id_song)
GROUP BY s.id
ORDER BY id DESC
Run Code Online (Sandbox Code Playgroud)
问题是,当一首歌有超过1个标签时,它会被多次返回,所以当我执行COUNT()时,它会返回更多结果.
我能想到的最好的解决方案是,如果能够在GROUP BY之后进行最后的LEFT JOIN(现在每首歌只有一个条目).然后我需要另一个GROUP BY m.id.
有没有办法实现这一目标?我需要使用子查询吗?
到目前为止,已经有了一些很好的答案,但我会采用一种与你原先描述的方法非常相似的方法
SELECT
songsWithTags.*,
COALESCE(SUM(v.vote),0) AS votesUp,
COALESCE(SUM(1-v.vote),0) AS votesDown
FROM (
SELECT
s.*,
COLLATE(GROUP_CONCAT(st.id_tag),'') AS tags_ids
FROM Songs s
LEFT JOIN Songs_Tags st
ON st.id_song = s.id
GROUP BY s.id
) AS songsWithTags
LEFT JOIN Votes v
ON songsWithTags.id = v.id_song
GROUP BY songsWithTags.id DESC
Run Code Online (Sandbox Code Playgroud)
在此,子查询负责将带有标签的歌曲整理为每首歌曲1行.然后将其加入投票.我还选择简单地总结v.votes列,因为你已经指出它是1或0,因此SUM(v.votes)将加起来1 + 1 + 1 + 0 + 0 = 3中的3个是upvotes,而SUM(1-v.vote)将总和0 + 0 + 0 + 1 + 1 = 2中的5个是downvotes.
如果你有一个带有列(id_song,vote)的投票索引,那么该索引将用于此,所以它甚至不会打到表.同样,如果您在Songs_Tags上有一个带有(id_song,id_tag)的索引,那么该表将不会被查询命中.
使用count 编辑添加的解决方案
SELECT
songsWithTags.*,
COUNT(CASE WHEN v.vote=1 THEN 1 END) as votesUp,
COUNT(CASE WHEN v.vote=0 THEN 1 END) as votesDown
FROM (
SELECT
s.*,
COLLATE(GROUP_CONCAT(st.id_tag),'') AS tags_ids
FROM Songs s
LEFT JOIN Songs_Tags st
ON st.id_song = s.id
GROUP BY s.id
) AS songsWithTags
LEFT JOIN Votes v
ON songsWithTags.id = v.id_song
GROUP BY songsWithTags.id DESC
Run Code Online (Sandbox Code Playgroud)
尝试这个:
SELECT
s.*,
GROUP_CONCAT(DISTINCT st.id_tag) AS tags_ids,
COUNT(DISTINCT CASE WHEN v.vote=1 THEN id_vote ELSE NULL END) AS votesUp,
COUNT(DISTINCT CASE WHEN v.vote=0 THEN id_vote ELSE NULL END) AS votesDown
FROM Songs s
LEFT JOIN Songs_Tags st ON (s.id = st.id_song)
LEFT JOIN Votes v ON (s.id=v.id_song)
GROUP BY s.id
ORDER BY id DESC
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
19227 次 |
| 最近记录: |