PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Usando UNNEST com um JOIN


Tecnicamente, sua consulta pode funcionar assim (não tenho certeza sobre o objetivo desta 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;

No entanto, parece-me que você está indo na direção errada aqui. Normalmente, seria removido o array redundante taglist e mantenha o esquema de banco de dados normalizado. Então sua consulta original deve servir bem, apenas encurtando a sintaxe com aliases:
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;

Desvendar o mistério


<rant> A causa raiz para seus "resultados diferentes" é a infeliz convenção de nomenclatura que alguns ORMs intelectualmente desafiados impor às pessoas.
Estou falando de id como nome da coluna. Nunca use esse antipadrão em um banco de dados com mais de uma tabela. Certo, isso significa basicamente qualquer base de dados. Assim que você se juntar a um monte de tabelas (é isso que você faz em um banco de dados) você acaba com um monte de colunas chamadas id . Totalmente inútil.
A coluna ID de uma tabela chamada tag deve ser tag_id (a menos que haja outro nome descritivo). Nunca id .</rant>

Sua consulta conta inadvertidamente tags em vez 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;

Deve funcionar desta forma:
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;

Eu também adicionei de volta o DISTINCT para o seu count() que se perdeu ao longo do caminho em sua consulta.