sql >> Database teknologi >  >> RDS >> PostgreSQL

To SQL LEFT JOINS giver et forkert resultat

Joins behandles fra venstre mod højre (medmindre andet er angivet i parenteser). Hvis du LEFT JOIN (eller bare JOIN , lignende effekt) tre dagligvarer til én bruger får du 3 rækker (1 x 3 ). Hvis du så tilmelder dig 4 fiskemarkeder for den samme bruger, får du 12 (3 x 4 ) rækker, multiplicerer den tidligere optælling i resultatet, ikke tilføjelse til det, som du måske havde håbet på.
Derved mangedobles besøgene for både dagligvarer og fiskemarkeder.

Du kan få det til at virke sådan her:

SELECT u.id
     , u.account_balance
     , g.grocery_visits
     , f.fishmarket_visits
FROM   users u
LEFT   JOIN (
   SELECT user_id, count(*) AS grocery_visits
   FROM   grocery
   GROUP  BY user_id
   ) g ON g.user_id = u.id
LEFT   JOIN (
   SELECT user_id, count(*) AS fishmarket_visits
   FROM   fishmarket
   GROUP  BY user_id
   ) f ON f.user_id = u.id
ORDER  BY u.id;

For at få aggregerede værdier for en eller få brugere, korrelerede underforespørgsler ligesom @Vince forudsat er helt fint. For en hel tabel eller større dele af den er det (meget) mere effektivt at samle n-tabellerne og slutte sig til resultatet en gang . På denne måde behøver vi heller ikke en anden GROUP BY i den ydre forespørgsel.

grocery_visits og fishmarket_visits er NULL for brugere uden relaterede poster i de respektive tabeller. Hvis du har brug for 0 i stedet (eller et hvilket som helst vilkårligt tal), brug COALESCE i den ydre SELECT :

SELECT u.id
     , u.account_balance
     , COALESCE(g.grocery_visits   , 0) AS grocery_visits
     , COALESCE(f.fishmarket_visits, 0) AS fishmarket_visits
FROM   ...


  1. Formater et tal som valuta i MariaDB

  2. Sådan indsætter du mere end 1000 værdier i en Oracle IN-klausul

  3. Ingen understøttelse af OVER i MS SQL Server 2005?

  4. PostgreSQL - FEJL:kolonnedato kan ikke castes til typedato