sql >> Databáze >  >> RDS >> PostgreSQL

Pomocí UNNEST s JOIN

Technicky může váš dotaz fungovat takto (nejste si zcela jisti cílem tohoto dotazu):

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;

Zdá se mi však, že zde jdete špatným směrem. Normálně by se odstranilo nadbytečné pole taglist a zachovat normalizované schéma databáze. Pak by měl váš původní dotaz dobře posloužit, pouze zkrácenou syntaxi pomocí 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;

Odhalte záhadu

<rant> Hlavní příčinou vašich „odlišných výsledků“ je nešťastná konvence pojmenování, kterou někteří intelektuálně zpochybňují ORM vnucovat lidem.
Mluvím o id jako název sloupce. Nikdy nepoužívejte tento anti-vzor v databázi s více než jednou tabulkou. Správně, to znamená v podstatě jakýkoli databáze. Jakmile se připojíte k hromadě stolů (to je to, co děláte v databázi) skončíte s hromadou sloupců s názvem id . Naprosto zbytečné.
Sloupec ID tabulky s názvem tag by měl být tag_id (pokud neexistuje jiný popisný název). Nikdy id .</rant>

Váš dotaz neúmyslně počítá tags místo 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;

Mělo by to fungovat takto:

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;

Také jsem přidal zpět DISTINCT k vašemu count() který se cestou ve vašem dotazu ztratil.



  1. Přesunout uzel ve stromu vnořených sad

  2. Proč SQL Server nepovažuje tento kód za chybný?

  3. Použití mysql COUNT k počítání více sloupců

  4. Seskupte podle období v intervalu týdnů/měsíců