SELECT *
FROM reservation
WHERE id NOT IN (select reservation_id
FROM reservation_log
WHERE change_type = 'cancel')
ATAU:
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
Versi pertama lebih intuitif, tetapi menurut saya versi kedua biasanya mendapatkan kinerja yang lebih baik (dengan asumsi Anda memiliki indeks pada kolom yang digunakan dalam gabungan).
Versi kedua berfungsi karena LEFT JOIN
mengembalikan baris untuk semua baris di tabel pertama. Saat ON
kondisi berhasil, baris tersebut akan menyertakan kolom dari tabel kedua, seperti INNER JOIN
. Ketika kondisi gagal, baris yang dikembalikan akan berisi NULL
untuk semua kolom di tabel kedua. WHERE l.id IS NULL
test kemudian mencocokkan baris tersebut, sehingga menemukan semua baris yang tidak memiliki kecocokan antar tabel.