The EXCEPT
Operator diperkenalkan pada SQL Server 2005 tapi apa perbedaan antara NOT IN
dan EXCEPT
?
Apakah itu melakukan hal yang sama? Saya ingin penjelasan sederhana dengan contoh.
sumber
The EXCEPT
Operator diperkenalkan pada SQL Server 2005 tapi apa perbedaan antara NOT IN
dan EXCEPT
?
Apakah itu melakukan hal yang sama? Saya ingin penjelasan sederhana dengan contoh.
Ada dua perbedaan utama antara EXCEPT
dan NOT IN
.
EXCEPT
memfilter DISTINCT
nilai dari tabel sebelah kiri yang tidak muncul di tabel sebelah kanan. Ini pada dasarnya sama dengan melakukan NOT EXISTS
dengan DISTINCT
klausa.
Itu juga mengharapkan dua tabel (atau subset kolom dari tabel) untuk memiliki jumlah kolom yang sama di sisi kiri dan kanan kueri
Misalnya, Anda tidak dapat melakukan:
SELECT ID, Name FROM TableA
EXCEPT
SELECT ID FROM TableB
Ini akan menghasilkan kesalahan:
Semua kueri yang digabungkan menggunakan operator UNION, INTERSECT atau EXCEPT harus memiliki jumlah ekspresi yang sama dalam daftar target mereka.
NOT IN
tidak memfilter untuk DISTINCT
nilai dan mengembalikan semua nilai dari tabel sebelah kiri yang tidak muncul di tabel sebelah kanan.
NOT IN
mengharuskan Anda membandingkan satu kolom dari satu tabel dengan satu kolom dari tabel atau subquery lain.
Misalnya, jika subquery Anda mengembalikan banyak kolom:
SELECT * FROM TableA AS nc
WHERE ID NOT IN (SELECT ID, Name FROM TableB AS ec)
Anda akan mendapatkan kesalahan berikut:
Hanya satu ekspresi yang dapat ditentukan dalam daftar pilih ketika subquery tidak diperkenalkan dengan EXISTS.
Namun, jika tabel sebelah kanan berisi NULL
nilai yang sedang difilter oleh NOT IN
, set hasil kosong dikembalikan, berpotensi memberikan hasil yang tidak terduga.
CREATE TABLE #NewCustomers (ID INT);
CREATE TABLE #ExistingCustomers (ID INT);
INSERT INTO #NewCustomers
( ID )
VALUES
(8), (9), (10), (1), (3), (8);
INSERT INTO #ExistingCustomers
( ID )
VALUES
( 1) , (2), (3), (4), (5);
-- EXCEPT filters for DISTINCT values
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN returns all values without filtering
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
Dari dua kueri di atas, EXCEPT
kembalikan 3 baris dari #NewCustomers
, saring 1 dan 3 yang cocok #ExistingCustomers
dan duplikat 8.
NOT IN
tidak melakukan penyaringan yang berbeda ini dan mengembalikan 4 baris dari #NewCustomers
dengan duplikat 8.
Jika sekarang kita menambahkan a NULL
ke #ExistingCustomers
tabel, kita melihat hasil yang sama dikembalikan oleh EXCEPT
, namun NOT IN
akan mengembalikan set hasil kosong.
INSERT INTO #ExistingCustomers
( ID )
VALUES
( NULL );
-- With NULL values in the right-hand table, EXCEPT still returns the same results as above
SELECT * FROM #NewCustomers AS nc
EXCEPT
SELECT * FROM #ExistingCustomers AS ec
-- NOT IN now returns no results
SELECT * FROM #NewCustomers AS nc
WHERE ID NOT IN (SELECT ID FROM #ExistingCustomers AS ec)
DROP TABLE #NewCustomers;
DROP TABLE #ExistingCustomers;
Alih-alih NOT IN
, Anda harus benar-benar melihat NOT EXISTS
dan ada perbandingan yang bagus antara keduanya di blog Gail Shaw .
Sebuah tambahan untuk komentar luar biasa Mark Sinkinson:
Anda sebenarnya bisa tampil
NOT IN
dengan lebih dari satu kolom.Misalnya ini adalah permintaan SQL * prefectly legal :
Yang akan kembali
first_name
danlast_name
semua orang yang adalah karyawan, tetapi tidak juga manajer.*: tetapi konstruksinya belum diimplementasikan dalam SQL Server.
sumber
NOT IN di atas gagal karena harus ada korelasi antara predikat dalam permintaan utama dan subquery. Jika Anda membiarkannya, Anda akan mendapatkan subquery yang tidak terkorelasi.
PILIH * DARI TableA SEBAGAI nc ID MANA TIDAK DI (SELECT ID, Nama DARI TableB SEBAGAI ec mana nc.ID = ec.ID)
KECUALI lebih baik dan akan menangani setiap baris nol tanpa menggunakan predikat IS NULL / IS NOT NULL.
sumber