SELECT *
FROM reservation
WHERE id NOT IN (select reservation_id
FROM reservation_log
WHERE change_type = 'cancel')
OPPURE:
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
La prima versione è più intuitiva, ma penso che la seconda versione di solito ottenga prestazioni migliori (supponendo che tu abbia indici sulle colonne utilizzate nel join).
La seconda versione funziona perché LEFT JOIN
restituisce una riga per tutte le righe della prima tabella. Quando il ON
condizione riesce, quelle righe includeranno le colonne della seconda tabella, proprio come INNER JOIN
. Quando la condizione non riesce, la riga restituita conterrà NULL
per tutte le colonne della seconda tabella. Il WHERE l.id IS NULL
test quindi abbina quelle righe, quindi trova tutte le righe che non hanno una corrispondenza tra le tabelle.