Setelah membacanya, ini bukan duplikat dari Bergabung SQL Eksplisit vs Implisit . Jawabannya mungkin terkait (atau bahkan sama) tetapi pertanyaannya berbeda.
Apa perbedaannya dan apa yang harus dilakukan pada masing-masing?
Jika saya memahami teori dengan benar, pengoptimal kueri harus dapat menggunakan keduanya secara bergantian.
Jawaban:
Mereka bukan hal yang sama.
Pertimbangkan pertanyaan ini:
dan
Yang pertama akan mengembalikan pesanan dan garisnya, jika ada, untuk nomor pesanan
12345
. Yang kedua akan mengembalikan semua pesanan, tetapi hanya pesanan yang12345
akan memiliki garis yang terkait dengannya.Dengan
INNER JOIN
, klausa secara efektif setara. Namun, hanya karena keduanya secara fungsional sama, dalam arti mereka menghasilkan hasil yang sama, tidak berarti kedua jenis klausa memiliki makna semantik yang sama.sumber
Hal-hal untuk gabungan luar
Sebuah.
WHERE
klausa: Setelah bergabung. Catatan akan disaring setelah bergabung telah terjadi.b.
ON
klausa - Sebelum bergabung. Rekaman (dari tabel kanan) akan difilter sebelum bergabung. Ini mungkin berakhir sebagai nol dalam hasil (sejak OUTER bergabung).Contoh : Pertimbangkan tabel di bawah ini:
a)
WHERE
Klausa di dalam :b)
JOIN
Klausa di dalamsumber
intermediate join table
? Perintah 'Jelaskan'?Pada saat
INNER JOIN
mereka dipertukarkan, dan pengoptimal akan mengatur ulang mereka di akan.Pada tanggal
OUTER JOIN
, mereka tidak perlu dipertukarkan, tergantung pada sisi mana mereka bergabung.Saya menempatkan mereka di kedua tempat tergantung pada keterbacaan.
sumber
Orders.Join( OrderLines, x => x.ID, x => OrderID, (o,l) => new {Orders = o, Lines = l}).Where( ol => ol.Orders.ID = 12345)
Cara saya melakukannya adalah:
Selalu masukkan ketentuan gabungan dalam
ON
klausa jika Anda melakukanINNER JOIN
. Jadi, jangan menambahkan kondisi WHERE ke klausa ON, letakkan mereka diWHERE
klausa.Jika Anda melakukan a
LEFT JOIN
, tambahkan kondisi WHERE keON
klausa untuk tabel di sisi kanan gabungan. Ini adalah suatu keharusan, karena menambahkan klausa WHERE yang mereferensikan sisi kanan join akan mengonversi join menjadi INNER JOIN.Pengecualian adalah ketika Anda mencari catatan yang tidak ada dalam tabel tertentu. Anda akan menambahkan referensi untuk pengenal yang unik (yang tidak pernah NULL) di KANAN JOIN meja dengan klausa WHERE cara ini:
WHERE t2.idfield IS NULL
. Jadi, satu-satunya waktu Anda harus mereferensikan tabel di sisi kanan bergabung adalah menemukan catatan-catatan yang tidak ada dalam tabel.sumber
Pada gabungan batin, mereka memiliki arti yang sama. Namun Anda akan mendapatkan hasil yang berbeda di gabung luar tergantung pada jika Anda memasukkan kondisi gabung di WHERE vs klausa ON. Lihatlah pertanyaan terkait ini dan jawaban ini (oleh saya).
Saya pikir itu masuk akal untuk menjadi kebiasaan selalu menempatkan kondisi bergabung dalam klausa ON (kecuali itu adalah join luar dan Anda benar-benar menginginkannya di klausa mana) karena membuatnya lebih jelas bagi siapa pun yang membaca kueri Anda pada kondisi apa tabel-tabel tersebut disambung, dan juga membantu mencegah klausa WHERE dari lusinan garis.
sumber
Hubungan meja
Mengingat kami memiliki tabel
post
danpost_comment
tabel berikut :The
post
memiliki catatan berikut:dan
post_comment
memiliki tiga baris berikut:SQL INNER BERGABUNG
Klausa SQL JOIN memungkinkan Anda untuk mengaitkan baris milik tabel yang berbeda. Misalnya, CROSS JOIN akan membuat Produk Cartesian yang berisi semua kemungkinan kombinasi baris antara dua tabel yang bergabung.
Meskipun CROSS JOIN berguna dalam skenario tertentu, sebagian besar waktu, Anda ingin bergabung dengan tabel berdasarkan kondisi tertentu. Dan, di situlah INNER BERGABUNG berperan.
SQL INNER JOIN memungkinkan kita untuk menyaring Produk Cartesian dari bergabung dengan dua tabel berdasarkan kondisi yang ditentukan melalui klausa ON.
SQL INNER JOIN - ON "selalu benar" kondisi
Jika Anda memberikan kondisi "selalu benar", INNER JOIN tidak akan memfilter rekaman yang bergabung, dan kumpulan hasil akan berisi Produk Cartesian dari dua tabel bergabung.
Misalnya, jika kami menjalankan query SQL INNER JOIN berikut:
Kami akan mendapatkan semua kombinasi
post
danpost_comment
catatan:Jadi, jika kondisi klausa ON "selalu benar", INNER JOIN sama dengan kueri CROSS JOIN:
SQL INNER JOIN - ON "selalu salah" kondisi
Di sisi lain, jika kondisi klausa ON "selalu salah", maka semua catatan yang bergabung akan disaring dan hasil yang ditetapkan akan kosong.
Jadi, jika kita menjalankan query SQL INNER JOIN berikut:
Kami tidak akan mendapatkan hasil apa pun:
Itu karena kueri di atas setara dengan kueri Gabung Gabung berikut:
SQL INNER JOIN - ON klausa menggunakan kolom Foreign Key dan Primary Key
Kondisi klausa ON paling umum adalah kondisi yang cocok dengan kolom Kunci Asing di tabel anak dengan kolom Kunci Utama di tabel induk, seperti yang diilustrasikan oleh permintaan berikut:
Saat menjalankan query SQL INNER JOIN di atas, kami mendapatkan hasil sebagai berikut:
Jadi, hanya catatan yang cocok dengan kondisi klausa ON yang termasuk dalam set hasil kueri. Dalam kasus kami, set hasil berisi semua
post
besertapost_comment
catatannya. Thepost
baris yang telah ada terkaitpost_comment
dikecualikan karena mereka tidak dapat memenuhi kondisi ON Clause.Sekali lagi, kueri SQL INNER JOIN di atas setara dengan kueri CROSS JOIN berikut:
Baris yang tidak disambar adalah yang memenuhi klausa WHERE, dan hanya catatan ini yang akan dimasukkan dalam hasil yang ditetapkan. Itulah cara terbaik untuk memvisualisasikan cara kerja klausa INNER JOIN.
Kesimpulan
Pernyataan INNER JOIN dapat ditulis ulang sebagai CROSS JOIN dengan klausa WHERE yang cocok dengan kondisi yang sama dengan yang Anda gunakan pada klausa ON dari permintaan INNER JOIN.
sumber
Ada perbedaan besar antara di mana klausa vs klausa , ketika datang ke kiri bergabung.
Berikut ini contohnya:
Ada fid id dari tabel t2.
Permintaan pada "pada klausa":
Pertanyaan tentang "di mana klausa":
Jelas bahwa, permintaan pertama mengembalikan catatan dari t1 dan baris dependennya dari t2, jika ada, untuk baris t1.v = 'K'.
Kueri kedua mengembalikan baris dari t1, tetapi hanya untuk t1.v = 'K' akan memiliki baris terkait dengannya.
sumber
Dalam hal pengoptimal, seharusnya tidak membuat perbedaan apakah Anda mendefinisikan klausa bergabung Anda dengan ON atau WHERE.
Namun, IMHO, saya pikir itu jauh lebih jelas untuk menggunakan klausa ON saat melakukan bergabung. Dengan cara itu Anda memiliki bagian spesifik dari kueri Anda yang menentukan bagaimana gabungan ditangani versus dicampur dengan klausa WHERE lainnya.
sumber
Mari kita perhatikan tabel-tabel itu:
SEBUAH
B
id_A
menjadi kunci asing ke mejaA
Menulis kueri ini:
Akan memberikan hasil ini:
Apa yang ada di A tetapi tidak di B berarti ada nilai null untuk B.
Sekarang, mari kita pertimbangkan bagian tertentu di
B.id_A
dalamnya, dan sorot dari hasil sebelumnya:Menulis kueri ini:
Akan memberikan hasil ini:
Karena ini menghapus di bagian dalam bergabung dengan nilai-nilai yang tidak ada di
B.id_A = SpecificPart
Sekarang, mari kita ubah kueri menjadi ini:
Hasilnya sekarang:
Karena seluruh hasil disaring agar tidak
B.id_A = SpecificPart
menghapus bagianB.id_A = NULL
, yang ada di A yang tidak di Bsumber
Apakah Anda mencoba menggabungkan data atau memfilter data?
Agar mudah dibaca, sebaiknya isolasi kasus penggunaan ini ke ON dan WHERE.
Sangat sulit untuk membaca kueri di mana kondisi GABUNG dan kondisi penyaringan ada di klausa WHERE.
Dari segi kinerja, Anda seharusnya tidak melihat perbedaan, meskipun beberapa tipe SQL terkadang menangani perencanaan kueri yang berbeda sehingga layak untuk dicoba
¯\_(ツ)_/¯
(Berhati-hatilah dengan caching yang memengaruhi kecepatan kueri)Juga seperti yang telah dicatat orang lain, jika Anda menggunakan gabungan luar Anda akan mendapatkan hasil yang berbeda jika Anda menempatkan kondisi filter dalam klausa ON karena hanya mempengaruhi salah satu tabel.
Saya menulis posting yang lebih mendalam tentang ini di sini: https://dataschool.com/learn/difference-between-where-and-on-in-sql
sumber
Dalam SQL, klausa 'WHERE' dan 'ON', adalah semacam Statistic Bersyarat, tetapi perbedaan utama di antara keduanya adalah, klausa 'Di mana' digunakan dalam Pernyataan Pilih / Pembaruan untuk menentukan Ketentuan, sedangkan klausa 'ON' digunakan dalam Bergabung, di mana ia memverifikasi atau memeriksa apakah Catatan Cocok dengan target dan tabel sumber, sebelum Tabel Bergabung
Misalnya: - 'DI MANA'
Sebagai Contoh: - 'ON'
Ada dua tabel pegawai dan rincian pegawai, kolom yang cocok adalah employee_id.
Semoga saya telah menjawab pertanyaan Anda. Kembalikan untuk klarifikasi apa pun.
sumber
WHERE
sebagai penggantiON
, bukan? sqlfiddle.com/#!2/ae5b0/14/0Saya pikir ini efek gabungan urutan. Dalam kasus bergabung kiri atas, SQL do Kiri bergabung dulu dan kemudian lakukan filter mana. Dalam kasus downer, cari Orders.ID = 12345 pertama, dan kemudian bergabung.
sumber
Untuk join batin,
WHERE
danON
bisa digunakan bergantian. Bahkan, dimungkinkan untuk digunakanON
dalam subquery yang dikorelasikan. Sebagai contoh:Ini (IMHO) benar-benar membingungkan manusia, dan sangat mudah untuk lupa menautkan
table1
apa pun (karena tabel "driver" tidak memiliki klausul "on"), tetapi ini legal.sumber
untuk tabel kinerja yang lebih baik harus memiliki kolom diindeks khusus untuk digunakan untuk BERGABUNG.
jadi jika kolom yang Anda kondisikan bukan salah satu dari kolom yang diindeks maka saya curiga lebih baik menyimpannya di MANA.
jadi Anda BERGABUNG menggunakan kolom yang diindeks, kemudian setelah BERGABUNG Anda menjalankan kondisi pada kolom tidak diindeks.
sumber
Biasanya, pemfilteran diproses dalam klausa WHERE setelah kedua tabel sudah digabungkan. Mungkin saja Anda ingin memfilter satu atau kedua tabel sebelum bergabung. yaitu, di mana klausa berlaku untuk seluruh hasil yang ditetapkan sedangkan klausa on hanya berlaku untuk gabungan tersebut.
sumber
Saya pikir perbedaan ini dapat dijelaskan melalui urutan operasi logis dalam SQL , yang disederhanakan:
FROM
(termasuk gabungan)WHERE
GROUP BY
HAVING
WINDOW
SELECT
DISTINCT
UNION
,INTERSECT
,EXCEPT
ORDER BY
OFFSET
FETCH
Bergabung bukan klausa pernyataan pilih, tetapi operator di dalamnya
FROM
. Dengan demikian, semuaON
klausa yang dimiliki olehJOIN
operator terkait telah "terjadi" secara logis pada saat pemrosesan logis mencapaiWHERE
klausa. Ini berarti bahwa dalam kasus aLEFT JOIN
, misalnya, semantik gabungan luar sudah bahagia pada saatWHERE
klausa diterapkan.Saya sudah menjelaskan contoh berikut ini secara lebih mendalam di posting blog ini . Saat menjalankan kueri ini:
Itu
LEFT JOIN
tidak benar-benar memiliki efek yang berguna, karena bahkan jika seorang aktor tidak bermain dalam film, aktor akan disaring, seperti yangFILM_ID
akan terjadiNULL
danWHERE
klausa akan menyaring baris seperti itu. Hasilnya adalah seperti:Yaitu seolah-olah kita batin bergabung dengan dua tabel. Jika kami memindahkan predikat filter dalam
ON
klausa, itu sekarang menjadi kriteria untuk gabungan luar:Berarti hasilnya akan berisi aktor tanpa film apa pun, atau tanpa film apa pun
FILM_ID < 10
Pendeknya
Selalu menempatkan predikat Anda di tempat yang paling masuk akal, secara logis.
sumber
Mengenai pertanyaan Anda,
Ini sama baik 'di' atau 'di mana' pada bergabung dalam selama server Anda bisa mendapatkannya:
dan
Opsi 'di mana' tidak semua penafsir tahu jadi mungkin harus dihindari. Dan tentu saja klausa 'on' lebih jelas.
sumber
ini solusi saya.
Anda harus memiliki yang
GROUP BY
untuk mendapatkannya untuk bekerja.Semoga bantuan ini.
sumber