TL;DR
ANY dan ALL di SQL dipakai buat bandingin satu nilai dengan sekumpulan nilai hasil subquery. ANY bernilai TRUE kalau perbandingannya cocok minimal ke satu nilai di list, sementara ALL baru TRUE kalau cocok ke semua nilai di list. Praktisnya, > ANY sama dengan lebih besar dari nilai terkecil, dan > ALL sama dengan lebih besar dari nilai terbesar.
ANY nyari baris yang cocok sama minimal satu nilai dari hasil subquery. ALL cuma lolosin baris yang cocok sama semua nilai di hasil subquery. Itu perbedaan intinya.
Dua operator ini jarang diajarin di tutorial SQL pemula. Padahal begitu kamu sering nulis query perbandingan, ANY dan ALL nghemat banyak baris.
Yang bikin orang keliru: > ANY itu artinya lebih besar dari yang paling kecil, bukan dari yang paling besar. Kebalik satu kali, hasil querynya bisa beda ratusan baris.
ANY adalah operator SQL yang bandingin satu nilai dengan setiap nilai di hasil subquery, lalu bernilai TRUE kalau minimal satu perbandingannya cocok. Operator ini selalu dipasangin sama operator pembanding: =, >, <, >=, <=, atau <>.
SELECT kolom
FROM tabel
WHERE nilai > ANY (SELECT kolom_lain FROM tabel_lain);
Di SQL Server, kamu bakal ketemu SOME. Artinya sama persis sama ANY, cuma sinonim.
Misalnya subquery balikin daftar harga: 18.000, 22.000. Lalu kamu tulis harga > ANY (...).
Baris dengan harga 25.000 lolos, karena 25.000 lebih besar dari 18.000. Cukup satu yang cocok.
Baris dengan harga 20.000 juga lolos, karena masih lebih besar dari 18.000. Baris dengan harga 15.000 gugur, soalnya semua nilai di list lebih besar darinya.
> ANY (list)= lebih besar dari MIN(list).< ANY (list)= lebih kecil dari MAX(list).
ALL bandingin satu nilai dengan setiap nilai di hasil subquery, dan baru bernilai TRUE kalau semua perbandingannya cocok. Satu aja gagal, barisnya kebuang.
SELECT kolom
FROM tabel
WHERE nilai > ALL (SELECT kolom_lain FROM tabel_lain);
Pakai list harga yang sama (18.000 dan 22.000), harga > ALL (...) cuma lolosin baris yang harganya di atas 22.000. Karena dia harus ngalahin dua-duanya.
> ALL (list)= lebih besar dari MAX(list).< ALL (list)= lebih kecil dari MIN(list).
Referensi resminya ada di dokumentasi subquery expressions PostgreSQL.
| Ditulis | Artinya | Padanan yang lebih jelas |
|---|---|---|
= ANY | Sama dengan salah satu | IN |
<> ALL | Beda dari semuanya | NOT IN |
> ANY | Lebih besar dari yang terkecil | > (SELECT MIN(...)) |
> ALL | Lebih besar dari yang terbesar | > (SELECT MAX(...)) |
< ANY | Lebih kecil dari yang terbesar | < (SELECT MAX(...)) |
< ALL | Lebih kecil dari yang terkecil | < (SELECT MIN(...)) |
= ALL | Sama dengan semuanya | Cuma masuk akal kalau list-nya 1 nilai |
<> ANY | Beda dari salah satu | Hampir selalu TRUE, jarang berguna |
Dua baris terakhir jarang kepakai. Kalau kamu nulis <> ANY, biasanya yang kamu maksud <> ALL.
Aku pakai tabel produk dari dataset ngulikdata (10 produk UMKM makanan, dari kopi Gayo sampai sambal roa). Struktur lengkapnya ada di blok SQL di bawah artikel ini, tinggal copy-paste.
SELECT nama_produk, kategori, harga
FROM produk
WHERE harga > ANY (
SELECT harga FROM produk WHERE kategori = 'Snack'
)
ORDER BY harga;
Kategori Snack isinya Keripik Singkong (18.000) dan Keripik Tempe (22.000). Harga termurahnya 18.000.
Hasilnya: 8 dari 10 produk lolos. Semua yang harganya di atas 18.000 masuk, termasuk Keripik Tempe sendiri yang harganya 22.000.
SELECT nama_produk, kategori, harga
FROM produk
WHERE harga > ALL (
SELECT harga FROM produk WHERE kategori = 'Snack'
)
ORDER BY harga;
Sekarang batasnya jadi 22.000, bukan 18.000. Hasilnya 7 produk. Teh Melati (25.000) masih masuk, tapi kedua keripik gugur.
Ganti satu kata dari ANY jadi ALL, hasilnya beda. Ini kenapa aku selalu ngetes dua-duanya sebelum masukin ke report.
SELECT nama_produk, harga
FROM produk
WHERE kategori = ANY (
SELECT kategori FROM produk WHERE harga > 90000
);
Subquery balikin kategori dari produk mahal: Minuman (Kopi Toraja 95.000) dan Herbal (Madu Hutan 145.000). Query utama lalu narik semua produk dari kedua kategori itu sekaligus.
Query ini bisa ditulis ulang pakai IN dan hasilnya identik:
WHERE kategori IN (SELECT kategori FROM produk WHERE harga > 90000)
Kalau maksudmu cuma ngecek keanggotaan, pakai IN. Lebih pendek dan lebih gampang dibaca tim. Detail lengkap soal subquery ada di artikel subquery SQL dengan 10 contoh praktis.
SELECT kota, SUM(qty) AS total_qty
FROM penjualan
GROUP BY kota
HAVING MIN(qty) > ALL (
SELECT AVG(qty) FROM penjualan
);
Rata-rata qty nasional di dataset ini 49 unit. Cuma Surabaya dan Bandung yang lolos. Tiap transaksi di dua kota itu qty-nya selalu di atas 49.
Insight praktisnya: dua kota ini pembelinya belanja borongan, bukan eceran. Strategi bundling lebih masuk akal dijalankan di sana daripada di Jakarta.
Jujur, sebagian besar kasus ANY dan ALL bisa ditulis ulang jadi bentuk yang lebih gampang dibaca:
IN atau NOT IN.> (SELECT MAX(...)) atau > (SELECT MIN(...)).EXISTS, biasanya lebih cepat karena bisa berhenti begitu ketemu satu.ANY dan ALL tetap layak dipakai di dua situasi. Pertama, waktu kondisinya susah dinyatakan pakai MIN atau MAX, misalnya perbandingan terhadap subquery berkorelasi. Kedua, waktu kamu baca query orang lain dan harus paham maksudnya.
Yang jelas, kamu wajib bisa baca keduanya. Query legacy di banyak perusahaan penuh sama pola ini.
Ini yang paling sering. Orang nulis harga > ANY (SELECT harga FROM produk WHERE kategori='Snack') sambil ngira artinya "lebih mahal dari semua snack". Padahal itu artinya "lebih mahal dari snack termurah".
Trik ngingetnya: ANY = cukup satu. ALL = harus semua.
Ini jebakan yang bikin orang bingung berjam-jam.
SELECT nama_produk
FROM produk
WHERE harga <> ALL (SELECT harga FROM produk WHERE diskon IS NULL);
Kalau subquery-nya balikin satu NULL aja, hasil perbandingannya jadi UNKNOWN. ALL butuh semuanya TRUE. Satu UNKNOWN bikin seluruh kondisi gagal, dan kamu dapet nol baris tanpa satu pun pesan error.
Fix-nya gampang: saring dulu NULL-nya:
WHERE harga <> ALL (
SELECT harga FROM produk WHERE harga IS NOT NULL
);
Masalah yang sama juga nyerang NOT IN. Pahami dulu perilaku NULL di SQL sebelum nulis query perbandingan yang rumit.
ANY dan ALL cuma bisa bandingin satu kolom. Kalau subquery-mu SELECT *, database bakal nolak dengan error "subquery has too many columns". Sebut kolomnya satu aja.
Kalau subquery gak balikin baris sama sekali, hasilnya kontra-intuitif. > ANY (kosong) selalu FALSE, gak ada yang bisa dicocokin. Tapi > ALL (kosong) selalu TRUE, karena secara logika, semua nol perbandingan otomatis lolos.
Jadi query pakai ALL bisa balikin seluruh tabel kalau subquery-nya kosong. Cek dulu subquery-nya sendirian sebelum digabung.
Kalau subquery-nya berkorelasi (ngereferensi kolom dari query luar), dia dieksekusi ulang buat tiap baris. Di tabel 2 juta baris, ini bikin query kamu ngegantung.
Pakai CTE buat ngitung nilai pembandingnya sekali, lalu bandingin ke situ.
= ANY hasilnya persis sama dengan IN. Bedanya, ANY bisa dipasangin operator perbandingan lain seperti > dan <, sementara IN cuma bisa ngecek kesamaan.
> ANY artinya lebih besar dari nilai terkecil di list. > ALL artinya lebih besar dari nilai terbesar. Banyak yang kebalik di sini.
Hampir pasti karena ada NULL di subquery. Tambahin IS NOT NULL di dalam subquery-nya.
Jalan di keduanya, plus PostgreSQL dan Oracle. SQL Server juga punya SOME yang artinya sama dengan ANY.
Performanya mirip di database modern, tapi versi MAX lebih gampang dibaca dan lebih aman dari jebakan NULL.
ANY = cukup satu cocok. ALL = harus semua cocok. Kalau bingung, terjemahin ke MIN atau MAX. Hasilnya sama dan bakal lebih gampang dibaca setahun ke depan.
Copy-paste blok SQL di artikel ini ke database latihanmu, jalanin nomor 1 dan 2, lalu bandingin jumlah barisnya. Beda satu kata, beda hasil.
Habis ini, mampir ke panduan subquery SQL atau cek referensi operator EXISTS yang sering jadi alternatif lebih cepat.
Mau praktek langsung? Mulai latihan SQL gratis
Latihan interaktif, langsung di browser.
Analisa per kuartal, hari kerja, atau musim jadi ribet kalau tiap query ngitung ulang atribut tanggal. Tabel kalender nyimpen semua atribut itu sekali, biar tinggal di-JOIN.
Laporan penjualan harian sering bolong di hari tanpa transaksi. Ini cara bikin deret tanggal lengkap di SQL biar tiap hari muncul, walau nilainya nol.
Struktur organisasi tersimpan sebagai kolom id_atasan yang saling nunjuk. Ini cara narik rantai jabatan, hitung total bawahan, dan span of control cuma pakai SQL.