PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Funções agregadas em várias tabelas unidas

SELECT f.id, f.name, b.fb_ct, t.tag_names
FROM   foo f
LEFT JOIN  (
    SELECT foo_id AS id, count(*) AS fb_ct
    FROM   foo_bar
    GROUP  BY 1
    ) b USING (id)
LEFT JOIN  (
    SELECT target_id AS id, array_agg(name) AS tag_names
    FROM   tag
    GROUP  BY 1
    ) t USING (id)
ORDER  BY f.id;

Produz o resultado desejado.

  • Reescreva com JOIN explícito sintaxe. Torna muito mais fácil de ler e entender (e depurar).

  • Ao ingressar em vários 1:n tabelas relacionadas, as linhas se multiplicariam produzindo um produto cartesiano - o que é um absurdo muito caro. É um CROSS JOIN não intencional por procuração. Relacionado:

  • Para evitar isso, participe de no máximo um n -table para o 1 -table antes de agregar (GROUP BY ). Você pode agregar duas vezes, mas é mais simples e rápido agregar n -tables separadamente antes juntando-os ao 1 -tabela.

  • Ao contrário do original (com INNER JOIN implícito) ). Eu uso LEFT JOIN para evitar perder linhas de foo que não têm linha correspondente em foo_bar ou tag .

  • Uma vez que o CROSS JOIN não intencional for removido da consulta, não há necessidade de adicionar DISTINCT mais - assumindo que foo.id é único.