SELECT *
FROM reservation
WHERE id NOT IN (select reservation_id
FROM reservation_log
WHERE change_type = 'cancel')
OF:
SELECT r.*
FROM reservation r
LEFT JOIN reservation_log l ON r.id = l.reservation_id AND l.change_type = 'cancel'
WHERE l.id IS NULL
De eerste versie is intuïtiever, maar ik denk dat de tweede versie meestal betere prestaties levert (ervan uitgaande dat je indexen hebt op de kolommen die in de join worden gebruikt).
De tweede versie werkt omdat LEFT JOIN
geeft een rij terug voor alle rijen in de eerste tabel. Wanneer de ON
voorwaarde slaagt, bevatten die rijen de kolommen uit de tweede tabel, net als INNER JOIN
. Als de voorwaarde faalt, bevat de geretourneerde rij NULL
voor alle kolommen in de tweede tabel. De WHERE l.id IS NULL
test komt dan overeen met die rijen, zodat het alle rijen vindt die geen overeenkomst hebben tussen de tabellen.