SELECT *
FROM reservation
WHERE id NOT IN (select reservation_id
FROM reservation_log
WHERE change_type = 'cancel')
ELLER:
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
Den första versionen är mer intuitiv, men jag tror att den andra versionen vanligtvis får bättre prestanda (förutsatt att du har index på kolumnerna som används i join).
Den andra versionen fungerar eftersom LEFT JOIN returnerar en rad för alla rader i den första tabellen. När ON villkoret lyckas, kommer dessa rader att inkludera kolumnerna från den andra tabellen, precis som INNER JOIN . När villkoret misslyckas kommer den returnerade raden att innehålla NULL för alla kolumner i den andra tabellen. WHERE l.id IS NULL testet matchar sedan dessa rader, så det hittar alla rader som inte har en matchning mellan tabellerna.