Sebagian besar dialek SQL menerima kedua pertanyaan berikut:
SELECT a.foo, b.foo
FROM a, b
WHERE a.x = b.x
SELECT a.foo, b.foo
FROM a
LEFT JOIN b ON a.x = b.x
Sekarang jelas ketika Anda membutuhkan gabungan luar, sintaks kedua diperlukan. Tetapi ketika melakukan inner join, mengapa saya lebih suka sintaks kedua daripada yang pertama (atau sebaliknya)?
Jawaban:
Sintaksis lama, dengan hanya mencantumkan tabel, dan menggunakan
WHERE
klausa untuk menentukan kriteria bergabung, sedang tidak digunakan di sebagian besar database modern.Ini bukan hanya untuk pertunjukan, sintaks lama memiliki kemungkinan ambigu ketika Anda menggunakan INNER dan OUTER bergabung dalam kueri yang sama.
Biarkan saya memberi Anda sebuah contoh.
Misalkan Anda memiliki 3 tabel di sistem Anda:
Setiap tabel berisi banyak baris, dihubungkan bersama. Anda memiliki banyak perusahaan, dan setiap perusahaan dapat memiliki banyak departemen, dan setiap departemen dapat memiliki beberapa karyawan.
Oke, jadi sekarang Anda ingin melakukan hal berikut:
Jadi kamu melakukan ini:
Perhatikan bahwa yang terakhir ada gabungan dalam, untuk memenuhi kriteria bahwa Anda hanya ingin departemen dengan orang.
Ok, jadi apa yang terjadi sekarang. Masalahnya adalah, itu tergantung pada mesin basis data, pengoptimal kueri, indeks, dan statistik tabel. Biarkan saya jelaskan.
Jika pengoptimal kueri menentukan bahwa cara untuk melakukan ini adalah pertama-tama mengambil sebuah perusahaan, kemudian menemukan departemen, dan kemudian bergabung dengan karyawan, Anda tidak akan mendapatkan perusahaan yang tidak memiliki departemen.
Alasan untuk ini adalah bahwa
WHERE
klausa menentukan baris mana berakhir pada hasil akhir, bukan bagian individu dari baris.Dan dalam hal ini, karena bergabung kiri, kolom Department.ID akan NULL, dan dengan demikian ketika datang ke INNER BERGABUNG ke Karyawan, tidak ada cara untuk memenuhi kendala itu untuk baris Karyawan, dan sehingga tidak akan muncul.
Di sisi lain, jika pengoptimal kueri memutuskan untuk menangani bergabung dengan departemen-karyawan terlebih dahulu, dan kemudian lakukan bergabung dengan kiri dengan perusahaan, Anda akan melihatnya.
Jadi sintaksis lama bersifat ambigu. Tidak ada cara untuk menentukan apa yang Anda inginkan, tanpa berurusan dengan petunjuk kueri, dan beberapa database tidak memiliki cara sama sekali.
Masukkan sintaks baru, dengan ini Anda dapat memilih.
Misalnya, jika Anda ingin semua perusahaan, seperti yang dijelaskan deskripsi masalah, inilah yang akan Anda tulis:
Di sini Anda menentukan bahwa Anda ingin bergabung dengan departemen-karyawan dilakukan sebagai satu bergabung, dan kemudian pergi bergabung dengan hasil itu dengan perusahaan.
Selain itu, katakanlah Anda hanya ingin departemen yang berisi huruf X atas namanya. Sekali lagi, dengan gaya lama bergabung, Anda berisiko kehilangan perusahaan juga, jika tidak memiliki departemen dengan X dalam namanya, tetapi dengan sintaks baru, Anda dapat melakukan ini:
Klausa tambahan ini digunakan untuk bergabung, tetapi bukan filter untuk seluruh baris. Jadi baris tersebut mungkin muncul dengan informasi perusahaan, tetapi mungkin memiliki NULL di semua kolom departemen dan karyawan untuk baris itu, karena tidak ada departemen dengan X dalam namanya untuk perusahaan itu. Ini sulit dengan sintaks lama.
Inilah sebabnya mengapa, di antara vendor lain, Microsoft telah mencabut sintaks join luar yang lama, tetapi bukan sintaks join dalam yang lama, sejak SQL Server 2005 dan yang lebih tinggi. Satu-satunya cara untuk berbicara dengan database yang berjalan di Microsoft SQL Server 2005 atau 2008, menggunakan sintaks join gaya lama, adalah dengan mengatur database itu dalam mode kompatibilitas 8.0 (alias SQL Server 2000).
Selain itu, cara lama, dengan melemparkan banyak tabel ke optimizer kueri, dengan sekelompok klausa WHERE, mirip dengan mengatakan "di sini Anda, lakukan yang terbaik yang Anda bisa". Dengan sintaks baru, optimizer kueri memiliki lebih sedikit pekerjaan yang harus dilakukan untuk mengetahui bagian mana yang berjalan bersama.
Jadi begitulah.
LEFT and INNER JOIN adalah gelombang masa depan.
sumber
OUTER JOIN
Sintaks yang tidak pernah standar*=
/=*
/*=*
sudah ditinggalkan.Sintaks GABUNG menjaga kondisi di dekat tabel yang mereka terapkan. Ini sangat berguna ketika Anda bergabung dengan sejumlah besar tabel.
Ngomong-ngomong, Anda bisa melakukan join luar dengan sintaks pertama juga:
Atau
Atau
sumber
Cara pertama adalah standar yang lebih lama. Metode kedua diperkenalkan di SQL-92, http://en.wikipedia.org/wiki/SQL . Standar lengkap dapat dilihat di http://www.contrib.andrew.cmu.edu/~shadow/sql/sql1992.txt .
Butuh bertahun-tahun sebelum perusahaan database mengadopsi standar SQL-92.
Jadi alasan mengapa metode kedua lebih disukai, itu adalah standar SQL menurut komite standar ANSI dan ISO.
sumber
,
masih standar.on
perlu diperkenalkan hanya untukouter join
satu kali subseleksi juga diperkenalkan.Pada dasarnya, ketika klausa FROM Anda mencantumkan tabel seperti:
hasilnya adalah produk silang dari semua baris dalam tabel A, B, C. Kemudian Anda menerapkan batasan
WHERE tableA.id = tableB.a_id
yang akan membuang sejumlah besar baris, lalu selanjutnya ...AND tableB.id = tableC.b_id
dan Anda kemudian harus mendapatkan hanya baris yang benar-benar Anda minati di.DBMS tahu bagaimana mengoptimalkan SQL ini sehingga perbedaan kinerja untuk menulis ini menggunakan BERGABUNG diabaikan (jika ada). Menggunakan notasi JOIN membuat pernyataan SQL lebih mudah dibaca (IMHO, tidak menggunakan gabungan mengubah pernyataan menjadi berantakan). Menggunakan produk silang, Anda harus memberikan kriteria bergabung dalam klausa WHERE, dan itulah masalahnya dengan notasi. Anda memenuhi klausa WHERE Anda dengan hal-hal seperti
yang hanya digunakan untuk membatasi produk silang. Klausa WHERE hanya boleh berisi BATASAN untuk resultset. Jika Anda mencampur tabel bergabung dengan kriteria dengan batasan resultset, Anda (dan orang lain) akan menemukan kueri Anda lebih sulit untuk dibaca. Anda harus menggunakan JOINs dan menjaga klausa FROM klausa FROM, dan klausa WHERE klausa WHERE.
sumber
Yang kedua lebih disukai karena jauh lebih kecil kemungkinannya untuk menghasilkan gabungan silang yang tidak disengaja dengan lupa memasukkan klausa mana. Gabung tanpa klausa akan gagal memeriksa sintaksis, gabung gaya lama tanpa klausa mana tidak akan gagal, ia akan melakukan join silang.
Selain itu ketika nanti Anda harus bergabung dengan kiri, akan membantu untuk pemeliharaan bahwa mereka semua berada dalam struktur yang sama. Dan sintaks yang lama telah kedaluwarsa sejak 1992, sudah saatnya untuk berhenti menggunakannya.
Ditambah lagi, saya telah menemukan bahwa banyak orang yang secara eksklusif menggunakan sintaks pertama tidak benar-benar memahami gabungan dan memahami gabungan sangat penting untuk mendapatkan hasil yang benar ketika mengajukan pertanyaan.
sumber
Saya pikir ada beberapa alasan bagus pada halaman ini untuk mengadopsi metode kedua - menggunakan JOINs eksplisit. Yang menentukan adalah bahwa ketika kriteria BERGABUNG dihapus dari klausa WHERE itu menjadi lebih mudah untuk melihat kriteria seleksi yang tersisa dalam klausa WHERE.
Dalam pernyataan SELECT yang sangat kompleks, pembaca akan lebih mudah memahami apa yang sedang terjadi.
sumber
The
SELECT * FROM table1, table2, ...
sintaks ok untuk beberapa tabel, tetapi menjadi eksponensial ( belum tentu pernyataan matematis akurat ) lebih keras dan lebih sulit untuk dibaca sebagai jumlah meja meningkat.Sintaks JOIN lebih sulit untuk ditulis (di awal), tetapi membuatnya eksplisit kriteria apa yang mempengaruhi tabel mana. Ini membuatnya lebih sulit untuk membuat kesalahan.
Juga, jika semua gabungan adalah INNER, maka kedua versi tersebut setara. Namun, saat Anda memiliki OUTER bergabung di mana saja dalam pernyataan, segala sesuatunya menjadi jauh lebih rumit dan itu sebenarnya menjamin bahwa apa yang Anda tulis tidak akan menanyakan apa yang Anda pikir Anda tulis.
sumber
Saat Anda membutuhkan gabung luar, sintaks kedua tidak selalu diperlukan:
Peramal:
MSSQLServer (meskipun sudah usang dalam versi 2000) / Sybase:
Tetapi kembali ke pertanyaan Anda. Saya tidak tahu jawabannya, tetapi mungkin terkait dengan fakta bahwa bergabung lebih alami (setidaknya secara sintaksis) daripada menambahkan ekspresi ke klausa di mana Anda melakukan hal itu: bergabung .
sumber
Saya mendengar banyak orang mengeluh yang pertama terlalu sulit untuk dipahami dan tidak jelas. Saya tidak melihat masalah dengan itu, tetapi setelah diskusi itu, saya menggunakan yang kedua bahkan pada INNER BERGABUNG untuk kejelasan.
sumber
Untuk basis data, mereka pada akhirnya sama saja. Namun, untuk Anda, Anda harus menggunakan sintaks kedua dalam beberapa situasi. Demi mengedit kueri yang akhirnya harus menggunakannya (mengetahui bahwa Anda memerlukan gabungan kiri di mana Anda memiliki gabungan langsung), dan untuk konsistensi, saya akan memodelkan hanya pada metode 2. Ini akan membuat kueri membaca lebih mudah.
sumber
Nah kueri pertama dan kedua dapat menghasilkan hasil yang berbeda karena LEFT JOIN menyertakan semua rekaman dari tabel pertama, bahkan jika tidak ada catatan yang sesuai di tabel sebelah kanan.
sumber