PostgreSQL
 sql >> Base de données >  >> RDS >> PostgreSQL

Postgres LEFT JOIN avec SUM, enregistrements manquants

Généralement plus rapide si vous récupérez toutes ou la plupart des lignes :

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;

Les index ne sont pas pertinents ici, les analyses complètes de la table seront les plus rapides. Sauf si les animaux de compagnie vivants sont rares cas, puis un index partiel devrait aider. Comme :

CREATE INDEX pets_alive_idx ON pets (person_id, kind) WHERE alive;

J'ai inclus toutes les colonnes nécessaires pour la requête (person_id, kind) pour autoriser les analyses d'index uniquement.

SQL Fiddle.

Généralement plus rapide pour un petit sous-ensemble ou une seule ligne :

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;

Vous devriez au moins avoir un index sur pets.person_id pour cela (ou l'index partiel ci-dessus) - et peut-être plus, selon le WHERE état.

Réponses associées :