Untuk kesederhanaan, anggap semua bidang yang relevan adalah NOT NULL
.
Anda dapat melakukan:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1, table2
WHERE
table1.foreignkey = table2.primarykey
AND (some other conditions)
Atau:
SELECT
table1.this, table2.that, table2.somethingelse
FROM
table1 INNER JOIN table2
ON table1.foreignkey = table2.primarykey
WHERE
(some other conditions)
Apakah keduanya bekerja dengan cara yang sama MySQL
?
sql
mysql
join
inner-join
JCCyC
sumber
sumber
Jawaban:
INNER JOIN
adalah sintaks ANSI yang harus Anda gunakan.Biasanya dianggap lebih mudah dibaca, terutama ketika Anda bergabung dengan banyak tabel.
Itu juga dapat dengan mudah diganti dengan
OUTER JOIN
setiap kali ada kebutuhan.The
WHERE
sintaks model yang lebih relasional berorientasi.Hasil dari dua tabel
JOIN
ed adalah produk cartesian dari tabel yang menerapkan filter yang hanya memilih baris-baris dengan kolom yang cocok.Lebih mudah untuk melihat ini dengan
WHERE
sintaks.Sebagai contoh Anda, di MySQL (dan dalam SQL umumnya) dua pertanyaan ini adalah sinonim.
Perhatikan juga bahwa MySQL juga memiliki
STRAIGHT_JOIN
klausa.Dengan menggunakan klausa ini, Anda dapat mengontrol
JOIN
urutan: tabel mana yang dipindai di loop luar dan yang mana di loop dalam.Anda tidak dapat mengontrol ini di MySQL menggunakan
WHERE
sintaks.sumber
Oracle
,SQL Server
,MySQL
danPostgreSQL
- ya. Untuk sistem lain, mungkin juga, tetapi Anda sebaiknya memeriksa.WHERE
klausa juga dalam standar ANSI.@Bill Karwin
:JOIN
kata kunci bukan bagian dari standar hak milik sampai masa lalu yang lebih baru. Itu membuat jalannya menjadiOracle
hanya dalam versi9
dan kePostgreSQL
dalam versi7.2
(keduanya dirilis pada2001
). Penampilan kata kunci ini adalah bagian dariANSI
adopsi standar, dan itulah sebabnya kata kunci ini biasanya dikaitkan denganANSI
, meskipun faktanya kata kunci ini mendukung koma sebagai sinonimCROSS JOIN
juga.WHERE
klausa (tanpa syarat, gabungan sama dengan gabungan silang, seperti yang Anda katakan). ANSI SQL-92 menambahkanJOIN
kata kunci dan sintaks terkait, tetapi sintaks gaya koma masih didukung untuk kompatibilitas mundur.Yang lain menunjukkan bahwa ini
INNER JOIN
membantu keterbacaan manusia, dan itu adalah prioritas utama, saya setuju.Biarkan saya mencoba menjelaskan mengapa sintaks bergabung lebih mudah dibaca.
SELECT
Permintaan dasar adalah ini:The
SELECT
klausul memberitahu kita apa yang sedang kita mendapatkan kembali; yangFROM
klausul memberitahu kita di mana kita mendapatkan itu dari, danWHERE
klausa memberitahu kita yang yang kita dapatkan.JOIN
adalah pernyataan tentang tabel, bagaimana mereka terikat bersama (secara konseptual, sebenarnya, menjadi satu tabel).Setiap elemen kueri yang mengontrol tabel - dari mana kita mendapatkan barang - semantik adalah milik
FROM
klausa (dan tentu saja, ke sanalahJOIN
elemen pergi). Menempatkan elemen bergabung ke dalamWHERE
klausa mengonfigurasikan mana dan di mana-dari , itu sebabnyaJOIN
sintaks lebih disukai.sumber
Menerapkan pernyataan bersyarat di ON / WHERE
Di sini saya telah menjelaskan tentang langkah-langkah pemrosesan query logis.
Referensi: Di dalam Microsoft® SQL Server ™ 2005 T-SQL
Penerbit Querying : Microsoft Press
Pub Tanggal: 07 Maret 2006
Cetak ISBN-10: 0-7356-2313-9
Cetak ISBN-13: 978-0-7356-2313-2
Halaman: 640
Di dalam Microsoft® SQL Server ™ 2005 T-SQL Querying
Aspek pertama yang terlihat dari SQL yang berbeda dari bahasa pemrograman lain adalah urutan di mana kode diproses. Di sebagian besar bahasa pemrograman, kode diproses sesuai urutan penulisan. Dalam SQL, klausa pertama yang diproses adalah klausa FROM, sedangkan klausa SELECT, yang muncul pertama, diproses hampir terakhir.
Setiap langkah menghasilkan tabel virtual yang digunakan sebagai input ke langkah berikut. Tabel virtual ini tidak tersedia untuk pemanggil (aplikasi klien atau permintaan luar). Hanya tabel yang dihasilkan oleh langkah terakhir yang dikembalikan ke pemanggil. Jika klausa tertentu tidak ditentukan dalam kueri, langkah yang sesuai hanya dilewati.
Deskripsi Singkat Fase Pemrosesan Kueri Logis
Jangan terlalu khawatir jika uraian langkah-langkahnya tampaknya tidak masuk akal untuk saat ini. Ini disediakan sebagai referensi. Bagian yang datang setelah contoh skenario akan mencakup langkah-langkah lebih detail.
DARI: Produk Cartesian (cross join) dilakukan antara dua tabel pertama dalam klausa FROM, dan sebagai hasilnya, tabel virtual VT1 dihasilkan.
ON: Filter ON diterapkan ke VT1. Hanya baris yang
<join_condition>
BENAR yang dimasukkan ke VT2.OUTER (gabung): Jika OUTER JOIN ditentukan (sebagai lawan dari CROSS JOIN atau INNER JOIN), baris dari tabel yang diawetkan atau tabel yang tidak ditemukan kecocokan ditambahkan ke baris dari VT2 sebagai baris luar, menghasilkan VT3. Jika lebih dari dua tabel muncul dalam klausa FROM, langkah 1 hingga 3 diterapkan berulang kali antara hasil dari join terakhir dan tabel berikutnya dalam klausa FROM sampai semua tabel diproses.
WHERE: Filter WHERE diterapkan ke VT3. Hanya baris yang
<where_condition>
BENAR yang dimasukkan ke VT4.KELOMPOK OLEH: Baris dari VT4 disusun dalam kelompok berdasarkan daftar kolom yang ditentukan dalam klausa GROUP BY. VT5 dihasilkan.
CUBE | ROLLUP: Supergroups (grup grup) ditambahkan ke baris dari VT5, menghasilkan VT6.
HAVING: Filter HAVING diterapkan ke VT6. Hanya grup yang
<having_condition>
bernilai BENAR yang dimasukkan ke VT7.SELECT: Daftar SELECT diproses, menghasilkan VT8.
DISTINCT: Baris duplikat dihapus dari VT8. VT9 dihasilkan.
ORDER BY: Baris dari VT9 diurutkan berdasarkan daftar kolom yang ditentukan dalam klausa ORDER BY. Kursor dihasilkan (VC10).
TOP: Jumlah atau persentase baris yang ditentukan dipilih dari awal VC10. Tabel VT11 dihasilkan dan dikembalikan ke pemanggil.
Karenanya, (INNER JOIN) ON akan memfilter data (jumlah data VT akan berkurang di sini sendiri) sebelum menerapkan klausa WHERE. Kondisi gabungan selanjutnya akan dieksekusi dengan data yang difilter yang meningkatkan kinerja. Setelah itu hanya kondisi WHERE yang akan menerapkan kondisi filter.
(Menerapkan pernyataan bersyarat dalam ON / WHERE tidak akan membuat banyak perbedaan dalam beberapa kasus. Ini tergantung pada berapa banyak tabel yang Anda telah bergabung dan jumlah baris yang tersedia di setiap tabel bergabung)
sumber
Implisit bergabung dengan sintaksis ANSI lebih tua, kurang jelas dan tidak direkomendasikan.
Selain itu, aljabar relasional memungkinkan pertukaran predikat dalam
WHERE
klausa dan klausaINNER JOIN
, sehingga bahkanINNER JOIN
pertanyaan denganWHERE
klausa dapat membuat predikat disusun ulang oleh pengoptimal.Saya sarankan Anda menulis kueri dengan cara yang paling mudah dibaca.
Kadang-kadang ini termasuk membuat yang
INNER JOIN
relatif "tidak lengkap" dan menempatkan beberapa kriteria dalamWHERE
hanya untuk membuat daftar kriteria penyaringan lebih mudah dipelihara.Misalnya, alih-alih:
Menulis:
Tapi itu tergantung, tentu saja.
sumber
Gabungan implisit (yang dikenal sebagai kueri pertama Anda) menjadi jauh lebih membingungkan, sulit dibaca, dan sulit dipertahankan begitu Anda perlu mulai menambahkan lebih banyak tabel ke kueri Anda. Bayangkan melakukan kueri dan tipe yang sama bergabung di empat atau lima tabel yang berbeda ... itu mimpi buruk.
Menggunakan gabungan eksplisit (contoh kedua Anda) jauh lebih mudah dibaca dan mudah dikelola.
sumber
Saya juga akan menunjukkan bahwa menggunakan sintaks yang lebih lama lebih banyak kesalahan. Jika Anda menggunakan gabungan dalam tanpa klausa ON, Anda akan mendapatkan kesalahan sintaksis. Jika Anda menggunakan sintaks yang lebih lama dan melupakan salah satu kondisi join di klausa where, Anda akan mendapatkan cross join. Pengembang sering memperbaikinya dengan menambahkan kata kunci yang berbeda (daripada memperbaiki gabungan karena mereka masih tidak menyadari bahwa sambungan itu sendiri rusak) yang mungkin muncul untuk menyembuhkan masalah, tetapi akan sangat memperlambat permintaan.
Selain itu untuk pemeliharaan jika Anda memiliki silang bergabung dalam sintaks lama, bagaimana pengelola tahu jika Anda bermaksud memilikinya (ada situasi di mana lintas bergabung diperlukan) atau jika itu kecelakaan yang harus diperbaiki?
Izinkan saya mengarahkan Anda ke pertanyaan ini untuk melihat mengapa sintaksis implisit buruk jika Anda menggunakan gabungan kiri. Sybase * = ke Ansi Standard dengan 2 tabel luar berbeda untuk tabel dalam yang sama
Plus (kata-kata kasar di sini), standar menggunakan gabungan eksplisit lebih dari 20 tahun, yang berarti sintaks join implisit telah usang selama 20 tahun tersebut. Apakah Anda akan menulis kode aplikasi menggunakan sintaks yang telah usang selama 20 tahun? Mengapa Anda ingin menulis kode basis data itu?
sumber
HAVING
yang telah 'usang' sejak SQL mulai mendukung tabel turunan. Saya juga melihat Anda tidak menggunakanNATURAL JOIN
meskipun saya berpendapat itu telahINNER JOIN
'usang'. Ya, Anda memiliki alasan Anda (tidak perlu menyatakannya lagi di sini!): Maksud saya adalah, mereka yang suka menggunakan sintaks yang lebih tua juga memiliki alasan mereka dan usia relatif dari sintaks adalah sedikit jika ada relevansi.Mereka memiliki makna berbeda yang bisa dibaca manusia.
Namun, tergantung pada pengoptimal kueri, mereka mungkin memiliki arti yang sama dengan mesin.
Anda harus selalu kode agar dapat dibaca.
Dengan kata lain, jika ini adalah hubungan bawaan, gunakan gabungan eksplisit. jika Anda cocok dengan data yang terkait lemah, gunakan klausa where.
sumber
Standar SQL: 2003 mengubah beberapa aturan diutamakan sehingga pernyataan JOIN diutamakan dari gabungan "koma". Ini sebenarnya dapat mengubah hasil permintaan Anda tergantung pada bagaimana pengaturannya. Ini menyebabkan beberapa masalah bagi sebagian orang ketika MySQL 5.0.12 beralih ke mengikuti standar.
Jadi, dalam contoh Anda, kueri Anda akan berfungsi sama. Tetapi jika Anda menambahkan tabel ketiga: SELECT ... FROM table1, table2 JOIN table3 ON ... WHERE ...
Sebelum ke MySQL 5.0.12, table1 dan table2 akan bergabung terlebih dahulu, kemudian table3. Sekarang (5.0.12 dan seterusnya), table2 dan table3 bergabung terlebih dahulu, kemudian table1. Itu tidak selalu mengubah hasil, tetapi bisa dan Anda bahkan mungkin tidak menyadarinya.
Saya tidak pernah menggunakan sintaks "koma" lagi, memilih contoh kedua Anda. Ini jauh lebih mudah dibaca, kondisi GABUNG adalah dengan GABUNGAN, tidak dipisahkan menjadi bagian permintaan yang terpisah.
sumber
Saya tahu Anda berbicara tentang MySQL, tetapi bagaimanapun juga: Dalam Oracle 9, bergabung secara eksplisit dan gabungan implisit akan menghasilkan rencana eksekusi yang berbeda. AFAIK yang telah dipecahkan di Oracle 10+: tidak ada perbedaan lagi.
sumber
Sintaks bergabung ANSI jelas lebih portabel.
Saya akan melalui peningkatan Microsoft SQL Server, dan saya juga akan menyebutkan bahwa sintaks = * dan * = untuk sambungan luar di SQL Server tidak didukung (tanpa mode kompatibilitas) untuk 2005 sql server dan yang lebih baru.
sumber
*=
dan=*
tidak pernah ANSI dan tidak pernah notasi yang baik. Karena itulah ON diperlukan - untuk OUTER JOINs tanpa adanya subselect (yang ditambahkan pada saat yang sama, sehingga mereka tidak benar-benar diperlukan dalam CROSS & INNER JOINs.)Jika Anda sering memprogram prosedur tersimpan dinamis, Anda akan jatuh cinta dengan contoh kedua Anda (menggunakan di mana). Jika Anda memiliki berbagai parameter input dan banyak kekacauan morf, maka itulah satu-satunya cara. Jika tidak, keduanya akan menjalankan rencana kueri yang sama sehingga pasti tidak ada perbedaan yang jelas dalam kueri klasik.
sumber