sql >> Base de Datos >  >> RDS >> PostgreSQL

Usando UNNEST con un JOIN

Técnicamente, su consulta podría funcionar así (no estoy completamente seguro del objetivo de esta consulta):

SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
FROM  (
    SELECT  unnest(m.taglist) AS tag_id
    FROM    mentions m
    WHERE   m.search_id = 3
    AND     9 = ANY (m.taglist)
    ) m 
JOIN   tags t  USING (tag_id) -- assumes tag.tag_id!
GROUP  BY t.parent_id;

Sin embargo, me parece que estás yendo en la dirección equivocada aquí. Normalmente, uno eliminaría la matriz redundante taglist y mantener el esquema de base de datos normalizado. Entonces su consulta original debería funcionar bien, solo acortó la sintaxis con alias:

SELECT 9 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id AS tag_id
FROM   mentions m
JOIN   taggings mt ON mt.mention_id = m.id
JOIN   tags     t  ON t.id = mt.tag_id
WHERE  9 = ANY (m.taglist)
AND    m.search_id = 3
GROUP  BY t.parent_id;

Desentrañar el misterio

<rant> La causa raíz de sus "resultados diferentes" es la desafortunada convención de nomenclatura que algunos desafiaron intelectualmente a los ORM imponer a las personas.
Estoy hablando de id como nombre de columna. Nunca use este antipatrón en una base de datos con más de una tabla. Correcto, eso significa básicamente cualquiera base de datos. Tan pronto como te unas a un grupo de mesas (eso es lo que haces en una base de datos) terminas con un montón de columnas llamadas id . Absolutamente inútil.
La columna ID de una tabla llamada tag debe ser tag_id (a menos que haya otro nombre descriptivo). Nunca id .</rant>

Su consulta cuenta inadvertidamente tags en lugar de mentions :

SELECT 25 AS keyword_id, count(m.id) AS total, t.parent_id AS tag_id
FROM  (
    SELECT unnest(m.taglist) AS id
    FROM   mentions m
    WHERE  m.search_id = 4
    AND    25 = ANY (m.taglist)
    ) m
JOIN   tags t USING (id)
GROUP  BY t.parent_id;

Debería funcionar de esta manera:

SELECT 25 AS keyword_id, count(DISTINCT m.id) AS total, t.parent_id
FROM  (
    SELECT m.id, unnest(m.taglist) AS tag_id
    FROM   mentions m
    WHERE  m.search_id = 4
    AND    25 = ANY (m.taglist)
    ) m
JOIN   tags t ON t.id =  m.tag_id
GROUP  BY t.parent_id;

También volví a agregar DISTINCT a su count() que se perdió en el camino en su consulta.