sql >> Base de Datos >  >> RDS >> Mysql

IZQUIERDA UNIRSE después de GRUPO POR?

Ha habido algunas buenas respuestas hasta ahora, pero adoptaría un método ligeramente diferente, bastante similar al que describiste originalmente

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

En esto, la subconsulta es responsable de recopilar canciones con etiquetas en una fila por canción. Esto luego se une a Votos después. También opté por simplemente resumir la columna v.votes como indicó que es 1 o 0 y, por lo tanto, SUM (v.votes) sumará 1+1+1+0+0 =3 de 5 son votos a favor, mientras que SUM(1-v.vote) sumará 0+0+0+1+1 =2 de 5 son votos negativos.

Si tuviera un índice de votos con las columnas (id_song,vote), entonces ese índice se usaría para esto, por lo que ni siquiera tocaría la mesa. Del mismo modo, si tuviera un índice en Songs_Tags con (id_song, id_tag), entonces la consulta no afectaría a esa tabla.

editar solución agregada usando 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