sql >> Database >  >> RDS >> PostgreSQL

Postgres LEFT JOIN met SUM, ontbrekende records

Meestal het snelst als u alle of de meeste rijen ophaalt :

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;

Indexen zijn hier niet relevant, volledige tabelscans zijn het snelst. Behalve als levende huisdieren zeldzaam zijn geval, dan een gedeeltelijke index zou moeten helpen. Vind ik leuk:

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

Ik heb alle kolommen opgenomen die nodig zijn voor de zoekopdracht (person_id, kind) om alleen-index scans toe te staan.

SQL Fiddle.

Meestal het snelst voor een kleine subset of een enkele rij :

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;

Je moet op zijn minst een index hebben op pets.person_id hiervoor (of de gedeeltelijke index van hierboven) - en mogelijk meer, afhankelijk van de WHERE staat.

Gerelateerde antwoorden:



  1. Gebruik TYPEPROPERTY() om informatie over een gegevenstype in SQL Server te retourneren

  2. Uitzondering verhogen in PL/SQL?

  3. sysdate en dbtimezone verschillend in Oracle Database

  4. SQL-injectie in Java en MySQL bij gebruik van meerdere query's