sql >> Base de Datos >  >> RDS >> PostgreSQL

Funciones agregadas en varias tablas 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;

Produce el resultado deseado.

  • Reescribir con JOIN explícito sintaxis. Hace que sea mucho más fácil de leer y comprender (y depurar).

  • Uniéndose a múltiples 1:n tablas relacionadas, las filas se multiplicarían entre sí produciendo un producto cartesiano - que es una tontería muy cara. Es un CROSS JOIN no intencionado por delegación. Relacionado:

  • Para evitar esto, únete como máximo a uno n -tabla al 1 -table antes de agregar (GROUP BY ). Podría agregar dos veces, pero es más limpio y rápido agregar n -tablas por separado antes uniéndolos al 1 -mesa.

  • A diferencia de su original (con INNER JOIN implícito ). Yo uso LEFT JOIN para evitar perder filas de foo que no tienen una fila coincidente en foo_bar o tag .

  • Una vez que el CROSS JOIN no deseado se elimina de la consulta, no es necesario agregar DISTINCT más - suponiendo que foo.id es único.