Effectief, WHERE
voorwaarden en JOIN
voorwaarden voor [INNER] JOIN
zijn 100 % equivalent in PostgreSQL. (Het is een goede gewoonte om expliciete JOIN
te gebruiken voorwaarden om zoekopdrachten gemakkelijker te lezen en te onderhouden).
Hetzelfde is niet waar voor een LEFT JOIN
gecombineerd met een WHERE
voorwaarde op een tafel rechts van de join. Het doel van een LEFT JOIN
is om alle rijen aan de linkerkant van de join te behouden, ongeacht een match aan de rechterkant. Als er geen overeenkomst wordt gevonden, wordt de rij uitgebreid met NULL
waarden voor kolommen aan de rechterkant. De handleiding:
LEFT OUTER JOIN
Eerst wordt een inner join uitgevoerd. Vervolgens wordt voor elke rij in T1 die niet voldoet aan de join-voorwaarde met een rij in T2, een samengevoegde rij toegevoegd met null-waarden in kolommen van T2. De samengevoegde tabel heeft dus altijd ten minste één rij voor elke rij in T1.
Als u vervolgens een WHERE
. toepast voorwaarde die iets anders vereist dan een NULL
waarde op kolommen met tabellen aan de rechterkant, maakt u het effect ongeldig en zet u de LEFT [OUTER] JOIN
met geweld om om te werken als een eenvoudige [INNER] JOIN
, alleen (mogelijk) duurder vanwege een ingewikkelder zoekplan.
In een query met veel samengevoegde tabellen, is het voor Postgres (of een RDBMS) moeilijk om het beste (of zelfs een goede) queryplan te vinden. Het aantal theoretisch mogelijke reeksen om tabellen samen te voegen groeit factorieel (!). Postgres gebruikt de "Generic Query Optimizer" voor de taak en er zijn enkele instellingen om deze te beïnvloeden.
De zoekopdracht verdoezelen met misleidende LEFT JOIN
zoals uiteengezet, maakt het werk van de queryplanner moeilijker, is misleidend voor menselijke lezers en duidt meestal op fouten in de querylogica.
Gerelateerde antwoorden voor problemen die hieruit voortkomen:
- Waarom is null gelijk aan geheel getal in WHERE?
- Query met LEFT JOIN retourneert geen rijen voor telling van 0
- SQL-query met behulp van outer join en beperking van onderliggende records voor elke ouder
- Linker buitenste join gedraagt zich als inner join
- Selecteer rijen die niet aanwezig zijn in een andere tabel
enz.