PostgreSQL
 sql >> Database >  >> RDS >> PostgreSQL

Utilizzo di UNNEST con un JOIN

Tecnicamente, la tua query potrebbe funzionare in questo modo (non del tutto sicuro dell'obiettivo di questa query):

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;

Tuttavia, mi sembra che tu stia andando nella direzione sbagliata qui. Normalmente si rimuove l'array ridondante taglist e mantenere lo schema del database normalizzato. Quindi la tua query originale dovrebbe funzionare bene, ha solo abbreviato la sintassi con gli 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;

Svela il mistero

<rant> La causa principale dei tuoi "risultati diversi" è la sfortunata convenzione di denominazione che alcuni hanno sfidato intellettualmente gli ORM imporre alle persone.
Sto parlando di id come nome della colonna. Non utilizzare mai questo anti-pattern in un database con più di una tabella. Esatto, significa sostanzialmente qualsiasi Banca dati. Non appena ti unisci a un gruppo di tavoli (è quello che fai). in un database) ti ritroverai con un mucchio di colonne denominate id . Assolutamente inutile.
La colonna ID di una tabella denominata tags dovrebbe essere tag_id (a meno che non ci sia un altro nome descrittivo). Mai id .</rant>

La tua query conta inavvertitamente tags invece di 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;

Dovrebbe funzionare in questo modo:

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;

Ho anche aggiunto di nuovo il DISTINCT al tuo count() che si è perso lungo la strada nella tua query.