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

Postgres LEFT JOIN com SUM, registros ausentes


Normalmente mais rápido se você buscar todas ou a maioria das linhas :
SELECT pp.id
     , COALESCE(pt.a_dog_ct, 0) AS alive_dogs_count
     , COALESCE(pt.a_cat_ct, 0) AS alive_cats_count
FROM   people pp
LEFT   JOIN (
   SELECT person_id
        , count(kind = 'dog' OR NULL) AS a_dog_ct
        , count(kind = 'cat' OR NULL) AS a_cat_ct
   FROM   pets
   WHERE  alive
   GROUP  BY 1
   ) pt ON pt.person_id = pp.id;

Índices são irrelevantes aqui, varreduras completas de tabela serão mais rápidas. Exceto se animais de estimação vivos são raros caso, então um índice parcial deve ajudar. Curti:
CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;

Incluí todas as colunas necessárias para a consulta (person_id, kind) para permitir varreduras somente de índice.

SQL Fiddle.

Normalmente mais rápido para um pequeno subconjunto ou uma única linha :
SELECT pp.id
     , count(kind = 'dog' OR NULL) AS alive_dogs_count
     , count(kind = 'cat' OR NULL) AS alive_cats_count
FROM   people pp
LEFT   JOIN pets pt ON pt.person_id = pp.id
                   AND pt.alive
WHERE  <some condition to retrieve a small subset>
GROUP  BY 1;

Você deve ter pelo menos um índice em pets.person_id para isso (ou o índice parcial acima) - e possivelmente mais, dependendo do WHERE doença.

Respostas relacionadas: