Salah satu fitur SQL yang paling hebat adalah operasi JOIN, yang menyediakan cara yang elegan dan sederhana untuk menggabungkan setiap baris dari satu tabel dengan setiap baris dari tabel lain. Namun, ada kalanya kita mungkin ingin menemukan nilai dari satu tabel yang TIDAK ada di tabel lain. Seperti yang akan kita lihat dalam artikel blog hari ini, join juga dapat digunakan untuk tujuan ini, dengan menyertakan predikat untuk menggabungkan tabel. Dikenal sebagai anti join, ini dapat membantu dalam menjawab berbagai pertanyaan terkait bisnis, seperti:
- Kustomer mana yang tidak memesan?
- Karyawan mana yang belum diberi departemen?
- Tenaga penjualan mana yang tidak menutup transaksi minggu ini?
Blog ini akan menawarkan primer tentang jenis anti join dan cara menulisnya menggunakan beberapa contoh berbasiskan pada dvdrental database akan menulis dan mengeksekusi query di Navicat Premium Lite 17.
Dua Tipe Anti Join
Terdapat dua tipe dari anti join:
- Left anti join: mengembalikan baris pada tabel kiri yang tidak memiliki baris yang cocok dengan tabel kanan
- Right anti join: mengembalikan baris pada tabel kanan yang tidak memiliki baris yang cocok dengan tabel kiri
Mengembalikan baris ditampilkan pada biru pada diagram dibawah:
Bagian berikutnya akan membahas beberapa syntax berbeda yang dapat kita gunakan untuk membuat anti join, menggunakan anti join kiri sebagai contoh.
Left Anti Join Menggunakan EXISTS
Katakanlah kita ingin menemukan semua aktor dalam database dvdrental yang tidak muncul dalam film apa pun. Sayangnya, SQL tidak memiliki syntax bawaan untuk operasi ini, tetapi kita dapat menirunya menggunakan EXISTS, atau, lebih khusus lagi, NOT EXISTS. Berikut ini adalah tampilan query tersebut:
SELECT * FROM actor a WHERE NOT EXISTS ( SELECT * FROM film_actor fa WHERE a.actor_id = fa.actor_id )
Jika kita menjalankannya di Navicat Premium Lite 17, kita akan mendapatkan hasil berikut:
Waspada pada NOT IN!
Karena EXISTS dan IN adalah ekuivalen, Anda mungkin tergoda untuk menyimpulkan bahwa NOT EXISTS dan NOT IN juga ekuivalen, tetapi ini tidak selalu terjadi! Keduanya hanya ekuivalen jika tabel yang tepat (dalam contoh ini, film_actor) memiliki batasan NOT NULL pada kunci asing (actor_id).
Pada contoh spesifik ini, query NOT IN mengembalikan hasil yang sama karena constraint NOT NULL pada kolom actor_id:
Jika kolom actor_id mengizinkan null, kumpulan hasil kosong akan dikembalikan. Kita dapat memverifikasi ini melalui query berikut:
SELECT * FROM actor WHERE actor_id NOT IN (1, 2, 3, 4, 5, NULL)
Query di atas tidak mengembalikan baris apa pun karena NULL mewakili nilai yang UNKNOWN dalam SQL. Karena kita tidak dapat memastikan apakah actor_id ada dalam sekumpulan nilai yang salah satunya UNKNOWN, seluruh predikatnya menjadi UNKNOWN!
Cara termudah untuk menghindari bahaya yang ditimbulkan oleh syntax NOT IN adalah dengan tetap menggunakan NOT EXISTS. Bahkan tidak ada gunanya mempertaruhkan keberadaan batasan NOT NULL karena DBA mungkin menonaktifkan batasan tersebut untuk sementara waktu guna memuat beberapa data, yang membuat query Anda tidak berguna untuk sementara waktu.
Syntax Alternatif
Seperti yang disinggung dalam pendahuluan, Anti Join juga dapat dilakukan menggunakan LEFT dan RIGHT JOIN. Agar hal itu berhasil, Anda perlu menambahkan klausa WHERE dengan predikat IS NULL. Berikut versi LEFT JOIN dari sintaks tersebut:
SELECT a.* FROM actor a LEFT JOIN film_actor fa ON a.actor_id = fa.actor_id WHERE fa.actor_id IS NULL
Hanya waspada bahwa syntax LEFT/RIGHT JOIN akan berjalan lebih lambat karena pengoptimal query tidak mengenalinya sebagai operasi ANTI JOIN.
Kesimpulan
Dalam blog hari ini, kita mempelajari cara meniru Left Anti Join menggunakan tiga variasi syntax SQL. Dari ketiganya, NOT EXISTS harus menjadi pilihan pertama Anda karena paling baik mengomunikasikan maksud ANTI JOIN dan cenderung berjalan paling cepat.
Tertarik mencoba Navicat Premium Lite 17? Anda dapat mengunduhnya untuk 14 hari uji coba GRATIS berfungsi penuh. Ini tersedia untuk system operasi Windows, macOS, dan Linux.