PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

Verwendung von UNNEST mit einem JOIN

Technisch gesehen könnte Ihre Abfrage so funktionieren (nicht ganz sicher über das Ziel dieser Abfrage):

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;

Allerdings scheint mir, dass du hier in die falsche Richtung gehst. Normalerweise würde man das redundante Array taglist entfernen und behalten Sie das normalisierte Datenbankschema bei. Dann sollte Ihre ursprüngliche Abfrage gute Dienste leisten, nur die Syntax mit Aliasnamen verkürzt:

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;

Lüfte das Geheimnis

<rant> Die Hauptursache für Ihre "unterschiedlichen Ergebnisse" ist die unglückliche Namenskonvention, die einige intellektuell herausgeforderte ORMs haben Menschen auferlegen.
Ich spreche von id als Spaltenname. Verwenden Sie dieses Antimuster niemals in einer Datenbank mit mehr als einer Tabelle. Richtig, das bedeutet im Grunde beliebig Datenbank. Sobald Sie an mehreren Tischen Platz nehmen (das tun Sie in einer Datenbank) erhalten Sie eine Reihe von Spalten mit dem Namen id . Völlig sinnlos.
Die ID-Spalte einer Tabelle namens tag sollte tag_id sein (es sei denn, es gibt einen anderen beschreibenden Namen). Nie id .</rant>

Ihre Abfrage zählt versehentlich tags statt 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;

Es sollte so funktionieren:

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;

Ich habe auch den DISTINCT wieder hinzugefügt zu Ihrem count() die in Ihrer Abfrage verloren gegangen sind.