sql >> Database >  >> RDS >> PostgreSQL

UNNEST gebruiken met een JOIN

Technisch gezien zou uw zoekopdracht als volgt kunnen werken (niet helemaal zeker over het doel van deze zoekopdracht):

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;

Het lijkt me echter dat je hier de verkeerde kant op gaat. Normaal gesproken zou men de redundante array taglist . verwijderen en behoud het genormaliseerde databaseschema. Dan zou je oorspronkelijke zoekopdracht goed moeten werken, alleen de syntaxis verkort met aliassen:

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;

Ontrafel het mysterie

<rant> De hoofdoorzaak voor uw "verschillende resultaten" is de ongelukkige naamgevingsconventie die sommige intellectueel uitgedaagde ORM's mensen opleggen.
Ik heb het over id als kolomnaam. Gebruik dit anti-patroon nooit in een database met meer dan één tabel. Juist, dat betekent in feite elke databank. Zodra je aan een aantal tafels deelneemt (dat is wat je doe in een database) krijg je een aantal kolommen met de naam id . Volkomen zinloos.
De ID-kolom van een tabel met de naam tag moet tag_id . zijn (tenzij er een andere beschrijvende naam is). Nooit id .</rant>

Uw zoekopdracht telt per ongeluk tags in plaats van 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;

Het zou op deze manier moeten werken:

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;

Ik heb ook de DISTINCT . terug toegevoegd naar je count() die onderweg verloren zijn gegaan in uw zoekopdracht.



  1. Hoe de prestaties voor SQLite-database voor Android te verbeteren

  2. Alleen-lezen- en lees-schrijftransacties splitsen met JPA en Hibernate

  3. PreparedStatement:Kan ik de kolomnaam als parameter opgeven?

  4. Automatisch opnieuw opvragen met LoaderManager