PostgreSQL
 sql >> Baza danych >  >> RDS >> PostgreSQL

Używanie UNNEST z JOIN

Z technicznego punktu widzenia Twoje zapytanie może działać w ten sposób (nie do końca pewne co do celu tego zapytania):

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;

Wydaje mi się jednak, że idziesz tutaj w złym kierunku. Normalnie można by usunąć nadmiarową tablicę taglist i zachowaj znormalizowany schemat bazy danych. Wtedy oryginalne zapytanie powinno działać dobrze, skrócono tylko składnię za pomocą aliasów:

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;

Rozwiąż tajemnicę

<rant> Podstawową przyczyną Twoich „różnych wyników” jest niefortunna konwencja nazewnictwa, którą niektóre zakwestionowane intelektualnie ORM narzucać ludziom.
Mówię o id jako nazwę kolumny. Nigdy nie używaj tego antywzorca w bazie danych z więcej niż jedną tabelą. Tak, oznacza to w zasadzie dowolne Baza danych. Gdy tylko dołączysz do kilku stołów (to właśnie robisz .) w bazie danych) otrzymujesz kilka kolumn o nazwie id . Całkowicie bez sensu.
Kolumna ID tabeli o nazwie tag powinien mieć wartość tag_id (chyba że istnieje inna nazwa opisowa). Nigdy id .</rant>

Twoje zapytanie przypadkowo zlicza tags zamiast 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;

Powinno działać w ten sposób:

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;

Dodałem również z powrotem DISTINCT do twojego count() które zgubiły się po drodze w zapytaniu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. PGError:ERROR:agregacje niedozwolone w klauzuli WHERE w zapytaniu AR obiektu i jego obiektów has_many

  2. Moje ulubione rozszerzenia PostgreSQL — część druga

  3. Jak zmapować znacznik czasu postgresql ze strefą czasową w jednostce JPA 2?

  4. KOPIUJ z dynamiczną nazwą pliku

  5. Jak zapisywać tablicę postgresql małymi literami?