SELECT *
FROM reservation
WHERE id NOT IN (select reservation_id
FROM reservation_log
WHERE change_type = 'cancel')
LUB:
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
Pierwsza wersja jest bardziej intuicyjna, ale myślę, że druga wersja zwykle uzyskuje lepszą wydajność (zakładając, że masz indeksy kolumn użytych w łączeniu).
Druga wersja działa, ponieważ LEFT JOIN
zwraca wiersz dla wszystkich wierszy w pierwszej tabeli. Gdy ON
warunek się powiedzie, te wiersze będą zawierać kolumny z drugiej tabeli, tak jak INNER JOIN
. Gdy warunek nie powiedzie się, zwrócony wiersz będzie zawierał NULL
dla wszystkich kolumn w drugiej tabeli. WHERE l.id IS NULL
test następnie dopasowuje te wiersze, więc znajduje wszystkie wiersze, które nie pasują do tabel.