Jawaban:
Kata existskunci dapat digunakan dengan cara itu, tetapi sebenarnya itu dimaksudkan sebagai cara untuk menghindari penghitungan:
--this statement needs to check the entire table
select count(*) from [table] where ...
--this statement is true as soon as one match is found
exists ( select * from [table] where ... )
Ini sangat berguna di mana Anda memiliki ifpernyataan bersyarat, karena existsbisa jauh lebih cepat daripada count.
Yang interbaik digunakan di mana Anda memiliki daftar statis untuk dilewati:
select * from [table]
where [field] in (1, 2, 3)
Ketika Anda memiliki tabel dalam inpernyataan, lebih masuk akal untuk menggunakan join, tetapi sebagian besar itu tidak masalah. Pengoptimal kueri harus mengembalikan paket yang sama. Dalam beberapa implementasi (kebanyakan lebih tua, seperti Microsoft SQL Server 2000) inkueri akan selalu mendapatkan paket bergabung bersarang , sementara joinkueri akan menggunakan bersarang, menggabungkan atau hash yang sesuai. Implementasi yang lebih modern lebih cerdas dan dapat menyesuaikan rencana bahkan ketika indigunakan.
select * from [table] where [field] in (select [field] from [table2])mengembalikan hasil yang sama (dan rencana kueri) sebagai select * from [table] join [table2] on [table2].[field] = [table].[field].
table, sedangkan yang kedua mengembalikan semuanya dari tabledan table2. Dalam beberapa (sebagian besar yang lebih tua) database SQL inkueri akan diimplementasikan sebagai bergabung bersarang, sementara joinkueri dapat bersarang, digabung, hash, dll - apa pun yang tercepat.
existsdapat digunakan dalam pernyataan kasus, sehingga mereka dapat berguna juga yaituselect case when exists (select 1 from emp where salary > 1000) then 1 else 0 end as sal_over_1000
EXISTSakan memberi tahu Anda apakah kueri mengembalikan hasil apa pun. misalnya:
SELECT *
FROM Orders o
WHERE EXISTS (
SELECT *
FROM Products p
WHERE p.ProductNumber = o.ProductNumber)
IN digunakan untuk membandingkan satu nilai dengan beberapa, dan dapat menggunakan nilai literal, seperti ini:
SELECT *
FROM Orders
WHERE ProductNumber IN (1, 10, 100)
Anda juga dapat menggunakan hasil kueri dengan INklausa, seperti ini:
SELECT *
FROM Orders
WHERE ProductNumber IN (
SELECT ProductNumber
FROM Products
WHERE ProductInventoryQuantity > 0)
Berdasarkan pengoptimal aturan :
EXISTSjauh lebih cepat daripada IN, ketika hasil sub-permintaan sangat besar.INlebih cepat daripada EXISTS, ketika hasil sub-permintaan sangat kecil.Berdasarkan pengoptimal biaya :
Saya berasumsi Anda tahu apa yang mereka lakukan, dan dengan demikian digunakan secara berbeda, jadi saya akan memahami pertanyaan Anda sebagai: Kapan ide yang baik untuk menulis ulang SQL untuk menggunakan IN daripada EXISTS, atau sebaliknya.
Apakah itu asumsi yang adil?
Sunting : Alasan saya bertanya adalah bahwa dalam banyak kasus Anda dapat menulis ulang SQL berdasarkan IN untuk menggunakan EXIS, dan sebaliknya, dan untuk beberapa mesin basis data, pengoptimal kueri akan memperlakukan keduanya secara berbeda.
Contohnya:
SELECT *
FROM Customers
WHERE EXISTS (
SELECT *
FROM Orders
WHERE Orders.CustomerID = Customers.ID
)
dapat ditulis ulang menjadi:
SELECT *
FROM Customers
WHERE ID IN (
SELECT CustomerID
FROM Orders
)
atau dengan bergabung:
SELECT Customers.*
FROM Customers
INNER JOIN Orders ON Customers.ID = Orders.CustomerID
Jadi pertanyaan saya masih berdiri, apakah poster asli bertanya-tanya tentang apa IN dan EXISTS, dan dengan demikian bagaimana menggunakannya, atau apakah dia bertanya apakah menulis ulang SQL menggunakan IN untuk menggunakan EXISTS sebagai gantinya, atau sebaliknya, akan menjadi ide yang baik?
JOIN, Anda membutuhkanDISTINCT
EXISTSjauh lebih cepat daripada INketika hasil subquery sangat besar.
INlebih cepat daripada EXISTSketika hasil subquery sangat kecil.
CREATE TABLE t1 (id INT, title VARCHAR(20), someIntCol INT)
GO
CREATE TABLE t2 (id INT, t1Id INT, someData VARCHAR(20))
GO
INSERT INTO t1
SELECT 1, 'title 1', 5 UNION ALL
SELECT 2, 'title 2', 5 UNION ALL
SELECT 3, 'title 3', 5 UNION ALL
SELECT 4, 'title 4', 5 UNION ALL
SELECT null, 'title 5', 5 UNION ALL
SELECT null, 'title 6', 5
INSERT INTO t2
SELECT 1, 1, 'data 1' UNION ALL
SELECT 2, 1, 'data 2' UNION ALL
SELECT 3, 2, 'data 3' UNION ALL
SELECT 4, 3, 'data 4' UNION ALL
SELECT 5, 3, 'data 5' UNION ALL
SELECT 6, 3, 'data 6' UNION ALL
SELECT 7, 4, 'data 7' UNION ALL
SELECT 8, null, 'data 8' UNION ALL
SELECT 9, 6, 'data 9' UNION ALL
SELECT 10, 6, 'data 10' UNION ALL
SELECT 11, 8, 'data 11'Pertanyaan 1
SELECT
FROM t1
WHERE not EXISTS (SELECT * FROM t2 WHERE t1.id = t2.t1id)
Pertanyaan 2
SELECT t1.*
FROM t1
WHERE t1.id not in (SELECT t2.t1id FROM t2 )
Jika dalam t1id Anda memiliki nilai nol maka Kueri 1 akan menemukannya, tetapi Kueri 2 tidak dapat menemukan parameter nol.
Maksud saya INtidak dapat membandingkan apa pun dengan nol, jadi tidak ada hasil untuk nol, tetapi EXISTSdapat membandingkan semuanya dengan nol.
Jika Anda menggunakan INoperator, mesin SQL akan memindai semua catatan yang diambil dari permintaan dalam. Di sisi lain jika kita menggunakan EXISTS, mesin SQL akan menghentikan proses pemindaian segera setelah menemukan kecocokan.
IN hanya mendukung hubungan kesetaraan (atau ketidaksetaraan ketika didahului oleh TIDAK ).
Ini adalah sinonim dari = any / = some , eg
select *
from t1
where x in (select x from t2)
;
EXISTS mendukung berbagai jenis hubungan, yang tidak dapat diekspresikan menggunakan IN , misalnya -
select *
from t1
where exists (select null
from t2
where t2.x=t1.x
and t2.y>t1.y
and t2.z like '℅' || t1.z || '℅'
)
;
Perbedaan kinerja dan teknis yang diduga antara EXISTS dan IN dapat terjadi akibat implementasi / batasan / bug vendor spesifik, tetapi sering kali mereka tidak lain hanyalah mitos yang diciptakan karena kurangnya pemahaman internal database.
Definisi tabel, akurasi statistik, konfigurasi basis data, dan versi pengoptimal memiliki semua dampak pada rencana eksekusi dan oleh karena itu pada metrik kinerja.
Kata Existskunci mengevaluasi benar atau salah, tetapi INkata kunci membandingkan semua nilai dalam kolom permintaan sub yang sesuai. Satu lagi Select 1dapat digunakan dengan Existsperintah. Contoh:
SELECT * FROM Temp1 where exists(select 1 from Temp2 where conditions...)
Tetapi INkurang efisien jadi Existslebih cepat.
Kupikir,
EXISTSadalah saat Anda harus mencocokkan hasil kueri dengan subquery lain. Hasil Query # 1 harus diambil di tempat yang cocok dengan hasil SubQuery. Jenis Bergabung. Misalnya memilih tabel pelanggan # 1 yang telah menempatkan tabel pesanan # 2 juga
IN adalah untuk mengambil jika nilai kolom tertentu terletak INdalam daftar (1,2,3,4,5). Mis. Pilih pelanggan yang berada dalam kode pos berikut ini, yaitu nilai-nilai zip_code terletak pada daftar (....).
Kapan harus menggunakan satu di atas yang lain ... ketika Anda merasa itu membaca dengan tepat (Berkomunikasi niat lebih baik).
Perbedaannya terletak di sini:
select *
from abcTable
where exists (select null)
Kueri di atas akan mengembalikan semua catatan sementara di bawah yang satu akan kembali kosong.
select *
from abcTable
where abcTable_ID in (select null)
Cobalah dan amati hasilnya.
Yang mana yang lebih cepat tergantung pada jumlah kueri yang diambil oleh kueri batin:
ADA mengevaluasi benar atau salah tetapi DI membandingkan nilai ganda. Ketika Anda tidak tahu catatan itu ada atau tidak, Anda harus memilih ADA
Alasannya adalah bahwa operator EXISTS bekerja berdasarkan prinsip "setidaknya ditemukan". Ini mengembalikan true dan berhenti memindai tabel sekali setidaknya satu baris yang cocok ditemukan.
Di sisi lain, ketika operator IN digabungkan dengan subquery, MySQL harus memproses subquery terlebih dahulu, dan kemudian menggunakan hasil dari subquery untuk memproses seluruh permintaan.
Aturan umum adalah bahwa jika subquery berisi sejumlah besar data, operator EXISTS memberikan kinerja yang lebih baik.
Namun, kueri yang menggunakan operator IN akan bekerja lebih cepat jika set hasil yang dikembalikan dari subquery sangat kecil.
Pemahaman saya adalah keduanya harus sama selama kita tidak berurusan dengan nilai NULL.
Alasan yang sama mengapa kueri tidak mengembalikan nilai untuk = NULL vs adalah NULL. http://sqlinthewild.co.za/index.php/2010/02/18/not-exists-vs-not-in/
Adapun argumen boolean vs komparator berjalan, untuk menghasilkan boolean kedua nilai perlu dibandingkan dan itulah bagaimana jika kondisi bekerja. Jadi saya gagal untuk memahami bagaimana IN dan EXISTS berperilaku berbeda.
In certain circumstances, it is better to use IN rather than EXISTS. In general, if the selective predicate is in the subquery, then use IN. If the selective predicate is in the parent query, then use EXISTS.
https://docs.oracle.com/cd/B19306_01/server.102/b14211/sql_1016.htm#i28403
Jika subquery mengembalikan lebih dari satu nilai, Anda mungkin perlu menjalankan query luar- jika nilai dalam kolom yang ditentukan dalam kondisi cocok dengan nilai apa pun di set hasil subquery. Untuk melakukan tugas ini, Anda perlu menggunakan inkata kunci.
Anda dapat menggunakan subquery untuk memeriksa apakah ada catatan. Untuk ini, Anda perlu menggunakan existsklausa dengan subquery. Kata existskunci selalu mengembalikan nilai benar atau salah.
Saya percaya ini memiliki jawaban langsung. Mengapa Anda tidak memeriksanya dari orang yang mengembangkan fungsi itu di sistem mereka?
Jika Anda seorang pengembang MS SQL, berikut ini jawabannya langsung dari Microsoft.
IN:
Menentukan apakah nilai yang ditentukan cocok dengan nilai apa pun di subquery atau daftar.
Menentukan subquery untuk menguji keberadaan baris.
Saya menemukan bahwa menggunakan kata kunci yang ada sering kali sangat lambat (itu sangat benar di Microsoft Access). Saya malah menggunakan operator bergabung dengan cara ini: harus-saya-gunakan-kata kunci-ada-di-sql
EXISTS Lebih Cepat dalam Kinerja daripada IN. Jika sebagian besar kriteria filter dalam subquery maka lebih baik untuk menggunakan IN dan Jika sebagian besar kriteria filter dalam permintaan utama maka lebih baik menggunakan EXISTS.
Jika Anda menggunakan operator IN, mesin SQL akan memindai semua catatan yang diambil dari permintaan dalam. Di sisi lain jika kita menggunakan EXIS, mesin SQL akan menghentikan proses pemindaian segera setelah menemukan kecocokan.
INdan EXISTSdapat setara dan ditransformasikan menjadi satu sama lain.
JOINsebagai penggantiIN.