@ avi gabung kiri dan kanan serupa, jika Anda tidak terganggu yang merupakan tabel utama bergabung berdasarkan.
Anup
2
@ philipxy: Itu definisi yang aneh (bahkan jika Anda benar). Tapi saya lebih suka berputar dan mulai dengan cross join dan kemudian "build" inner join di atasnya. Lagipula, konsep cross join belaka membuat visualisasi diagram Venn yang informal dan tidak akurat ini ...
Lukas Eder
1
Gambar-gambar ini tampaknya menyiratkan bahwa persatuan sama dengan gabungan luar penuh dan persimpangan sama dengan gabungan dalam yang tidak benar sejauh yang saya tahu.
mightyWOZ
1
@DevDave, karena bertentangan dengan kepercayaan populer - gambar tidak bernilai ribuan kata. Lihat jawaban selanjutnya.
hyankov
248
Apa SQL JOIN?
SQL JOIN adalah metode untuk mengambil data dari dua atau lebih tabel database.
Dalam jenis a ini JOIN, kami mendapatkan semua catatan yang cocok dengan kondisi di kedua tabel, dan catatan di kedua tabel yang tidak cocok tidak dilaporkan.
Dengan kata lain, INNER JOINdidasarkan pada fakta tunggal bahwa: HANYA entri yang cocok dalam KEDUA tabel HARUS dicantumkan.
Perhatikan bahwa JOINtanpa lainnya JOINkata kunci (seperti INNER, OUTER, LEFT, dll) adalah INNER JOIN. Dengan kata lain, JOINadalah gula sintaksis untuk INNER JOIN(lihat: Perbedaan antara BERGABUNG dan BERGABUNG DALAM ).
2. GABUNG LUAR:
OUTER JOIN mengambil
Entah, baris yang cocok dari satu tabel dan semua baris di tabel lain Atau, semua baris di semua tabel (tidak masalah apakah ada kecocokan atau tidak).
Ada tiga jenis Outer Join:
2.1 BERGABUNG LEFT OUTER atau LEFT JOIN
Gabung ini mengembalikan semua baris dari tabel kiri bersamaan dengan baris yang cocok dari tabel kanan. Jika tidak ada kolom yang cocok di tabel kanan, itu mengembalikan NULLnilai.
2.2 BERGABUNG DENGAN BENAR atau BERGABUNG KANAN
Ini JOINmengembalikan semua baris dari tabel kanan bersamaan dengan baris yang cocok dari tabel kiri. Jika tidak ada kolom yang cocok di tabel sebelah kiri, itu mengembalikan NULLnilai.
2.3 BERGABUNG FULL OUTER atau FULL JOIN
Ini JOINmenggabungkan LEFT OUTER JOINdan RIGHT OUTER JOIN. Ini mengembalikan baris dari tabel mana pun ketika kondisi terpenuhi dan mengembalikan NULLnilai ketika tidak ada kecocokan.
Dengan kata lain, OUTER JOINdidasarkan pada kenyataan bahwa: HANYA entri yang cocok di SALAH SATU tabel (KANAN atau KIRI) atau KEDUA tabel (PENUH) HARUS dicantumkan.
Note that `OUTERJOIN`is a loosened form of`INNERJOIN`.
3. GABUNG ALAMI:
Ini didasarkan pada dua kondisi:
yang JOINdibuat pada semua kolom dengan nama yang sama untuk kesetaraan.
Menghapus kolom duplikat dari hasilnya.
Ini tampaknya lebih bersifat teoritis dan sebagai hasilnya (mungkin) sebagian besar DBMS bahkan tidak repot-repot mendukung ini.
4. LINTAS BERGABUNG:
Ini adalah produk Cartesian dari dua tabel yang terlibat. Hasil dari CROSS JOINtidak akan masuk akal di sebagian besar situasi. Selain itu, kita tidak akan membutuhkan ini sama sekali (atau perlu paling tidak, tepatnya).
5. BERGABUNG DIRI:
Ini bukan bentuk yang berbeda dari JOIN, melainkan merupakan JOIN( INNER, OUTER, dll) dari meja untuk dirinya sendiri.
GABUNG berdasarkan Operator
Bergantung pada operator yang digunakan untuk JOINklausa, mungkin ada dua jenis JOINs. Mereka
Equi GABUNG
Theta BERGABUNG
1. Equi BERGABUNG:
Untuk JOINjenis apa pun ( INNER,, OUTERdll), jika kita HANYA menggunakan operator persamaan (=), maka kita mengatakan bahwa itu JOINadalah EQUI JOIN.
2. Theta BERGABUNG:
Ini sama seperti EQUI JOINtetapi memungkinkan semua operator lain seperti>, <,> = dll.
Banyak yang menganggap keduanya EQUI JOINdan Theta JOINmirip dengan INNER, OUTER
dll JOIN. Tapi saya sangat percaya bahwa ini adalah kesalahan dan membuat ide-ide itu kabur. Karena INNER JOIN, OUTER JOINdll semua terhubung dengan tabel dan data mereka sedangkan EQUI JOINdan THETA JOINhanya terhubung dengan operator yang kami gunakan di yang sebelumnya.
Sekali lagi, ada banyak orang yang menganggapnya NATURAL JOINsebagai "aneh" EQUI JOIN. Sebenarnya, itu benar, karena syarat pertama yang saya sebutkan NATURAL JOIN. Namun, kita tidak harus membatasi itu hanya untuk NATURAL JOINs saja. INNER JOINs, OUTER JOINs dll bisa menjadi EQUI JOINterlalu.
Ada LATERAL GABUNG yang relatif baru .. PILIH * DARI r1, LATERAL fx (r1)
Pavel Stehule
13
Meskipun ini tampaknya masuk akal, saya tidak berpikir jawaban "apa itu bergabung SQL" dengan cara apa pun yang menyampaikan informasi yang berguna. Jawabannya secara keseluruhan adalah referensi yang ditulis untuk orang-orang yang sudah mengerti bergabung, bukan untuk orang-orang yang bertanya. Ini juga menghilangkan referensi, baik untuk mendukung klaimnya (sebagaimana yang tepat jika membuat jawaban otoritatif) dan untuk memberikan penjelasan tambahan melalui sumber daya eksternal. Jika Anda mencoba menulis jawaban resmi untuk menautkan pengguna SQL baru, mungkin ada baiknya sedikit mengisi bagian yang kosong, terutama bagian "apa yang bergabung".
Craig Ringer
dapatkah Anda memberikan beberapa contoh?
avi
67
Definisi:
BERGABUNG adalah cara untuk meminta data yang digabungkan bersama dari beberapa tabel secara bersamaan.
Jenis GABUNGAN:
Mengenai RDBMS ada 5 jenis gabungan:
Equi-Join: Menggabungkan catatan umum dari dua tabel berdasarkan kondisi kesetaraan. Secara teknis, Gabung dibuat dengan menggunakan operator kesetaraan (=) untuk membandingkan nilai-nilai Kunci Utama dari satu tabel dan nilai-nilai Kunci Asing dari tabel lain, maka set hasil mencakup catatan umum (cocok) dari kedua tabel. Untuk implementasi, lihat INNER-JOIN.
Natural-Join: Ini adalah versi yang disempurnakan dari Equi-Join, di mana operasi SELECT menghilangkan kolom duplikat. Untuk implementasi, lihat INNER-JOIN
Non-Equi-Join: Ini adalah kebalikan dari Equi-join di mana kondisi bergabung menggunakan selain dari operator yang sama (=) misalnya,! =, <=,> =, BETWEEN dll. Untuk implementasi, lihat INNER-JOIN.
Gabung Sendiri:: Perilaku bergabung yang disesuaikan di mana tabel dikombinasikan dengan dirinya sendiri; Ini biasanya diperlukan untuk menanyakan tabel referensi-sendiri (atau entitas hubungan Unary). Untuk implementasi, lihat INNER-JOINs.
Produk Cartesian: Ini lintas menggabungkan semua catatan dari kedua tabel tanpa kondisi apa pun. Secara teknis, ini mengembalikan set hasil kueri tanpa WHERE-Clause.
Sehubungan dengan kepedulian dan kemajuan SQL, ada 3 jenis gabungan dan semua gabungan RDBMS dapat dicapai dengan menggunakan jenis gabungan ini.
INNER-JOIN: Menggabungkan (atau menggabungkan) baris yang cocok dari dua tabel. Pencocokan dilakukan berdasarkan kolom umum tabel dan operasi pembandingannya. Jika kondisi berdasarkan kesetaraan maka: EQUI-JOIN dilakukan, jika tidak Non-EQUI-Bergabung.
OUTER-JOIN: Menggabungkan (atau menggabungkan) baris yang cocok dari dua tabel dan baris yang tidak cocok dengan nilai NULL. Namun, dapat mengkustomisasi pemilihan baris yang tidak cocok misalnya, memilih baris yang tidak cocok dari tabel pertama atau tabel kedua berdasarkan sub-tipe: LEFT OUTER JOIN dan RIGHT OUTER JOIN.
2.1. LEFT Outer JOIN (alias, LEFT-JOIN): Mengembalikan baris yang cocok dari dua tabel dan tidak cocok dengan tabel LEFT (yaitu, tabel pertama).
2.2. RIGHT Outer JOIN (alias, RIGHT-JOIN): Mengembalikan baris yang cocok dari dua tabel dan tidak cocok dengan tabel RIGHT saja.
2.3. FULL OUTER JOIN (alias OUTER JOIN): Pengembalian cocok dan tidak cocok dari kedua tabel.
GABUNG-GABUNG: Gabung ini tidak menggabungkan / menggabungkan melainkan melakukan produk Cartesian.
Catatan: Self-JOIN dapat diraih oleh INNER-JOIN, OUTER-JOIN dan CROSS-JOIN berdasarkan persyaratan tetapi tabel harus bergabung dengan dirinya sendiri.
Label "Tabel 1" & "Tabel 2" & label di bawahnya tidak sesuai, berasal dari ilustrasi intersect/ except/ union; di sini lingkaran adalah baris yang dikembalikan oleh left& rightjoin, seperti yang dikatakan label bernomor. Gambar AXB adalah omong kosong. cross join= inner join on 1=1& adalah kasus khusus dari diagram pertama.
philipxy
Perlu disebutkan SQL-92 mendefinisikan UNION JOIN. Sekarang dibuat usang dalam SQL: 2003.
The Impaler
40
Menariknya, sebagian besar jawaban lain menderita dua masalah ini:
Pertama dan terpenting: GABUNG adalah produk kartesius
Inilah sebabnya mengapa diagram Venn menjelaskannya secara tidak akurat, karena JOIN membuat produk kartesius di antara dua tabel yang digabungkan. Wikipedia menggambarkannya dengan baik:
Sintaks SQL untuk produk kartesius adalah CROSS JOIN. Sebagai contoh:
SELECT*-- This just generates all the days in January 2017FROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Here, we're combining all days with all departmentsCROSSJOIN departments
Yang menggabungkan semua baris dari satu tabel dengan semua baris dari tabel lainnya:
Sumber:
+--------+ +------------+
| day | | department |
+--------+ +------------+
| Jan 01 | | Dept 1 |
| Jan 02 | | Dept 2 |
| ... | | Dept 3 |
| Jan 30 | +------------+
| Jan 31 |
+--------+
Hasil:
+--------+------------+
| day | department |
+--------+------------+
| Jan 01 | Dept 1 |
| Jan 01 | Dept 2 |
| Jan 01 | Dept 3 |
| Jan 02 | Dept 1 |
| Jan 02 | Dept 2 |
| Jan 02 | Dept 3 |
| ... | ... |
| Jan 31 | Dept 1 |
| Jan 31 | Dept 2 |
| Jan 31 | Dept 3 |
+--------+------------+
Jika kita hanya menulis daftar tabel yang dipisahkan koma, kita akan mendapatkan yang sama:
-- CROSS JOINing two tables:SELECT*FROM table1, table2
INNER JOIN (Theta-JOIN)
An INNER JOINhanya disaring di CROSS JOINmana predikat filter disebut Thetadalam aljabar relasional.
Misalnya:
SELECT*-- Same as beforeFROM generate_series('2017-01-01'::TIMESTAMP,'2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
INTERVAL '1 day')AS days(day)-- Now, exclude all days/departments combinations for-- days before the department was createdJOIN departments AS d ON day >= d.created_at
Perhatikan bahwa kata kunci INNERadalah opsional (kecuali dalam MS Access).
Jenis khusus Theta-JOIN adalah equi JOIN, yang paling sering kita gunakan. Predikat bergabung dengan kunci utama dari satu tabel dengan kunci asing dari tabel lain. Jika kita menggunakan database Sakila untuk ilustrasi, kita dapat menulis:
SELECT*FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id
Ini menggabungkan semua aktor dengan film mereka.
Atau juga, pada beberapa database:
SELECT*FROM actor
JOIN film_actor USING(actor_id)JOIN film USING(film_id)
The USING()sintaks memungkinkan untuk menentukan kolom yang harus hadir di kedua sisi dari BERGABUNG meja operasi dan menciptakan predikat kesetaraan pada dua kolom.
GABUNG ALAMI
Jawaban lain telah mencantumkan "tipe GABUNG" ini secara terpisah, tetapi itu tidak masuk akal. Ini hanya bentuk gula sintaksis untuk equi JOIN, yang merupakan kasus khusus dari Theta-JOIN atau INNER JOIN. GABUNG ALAMI hanya mengumpulkan semua kolom yang umum untuk kedua tabel yang bergabung dan bergabung USING()dengan kolom tersebut. Yang hampir tidak pernah berguna, karena kecocokan yang tidak disengaja (seperti LAST_UPDATEkolom dalam database Sakila ).
Inilah sintaksinya:
SELECT*FROM actor
NATURALJOIN film_actor
NATURALJOIN film
OUTER BERGABUNG
Sekarang, OUTER JOINsedikit berbeda dari INNER JOINkarena ia menciptakan UNIONbeberapa produk kartesius. Kita bisa menulis:
-- Convenient syntax:SELECT*FROM a LEFTJOIN b ON<predicate>-- Cumbersome, equivalent syntax:SELECT a.*, b.*FROM a JOIN b ON<predicate>UNIONALLSELECT a.*,NULL,NULL,...,NULLFROM a
WHERENOTEXISTS(SELECT*FROM b WHERE<predicate>)
Tidak ada yang mau menulis yang terakhir, jadi kami menulis OUTER JOIN(yang biasanya lebih baik dioptimalkan oleh basis data).
Seperti INNER, kata kunci OUTERbersifat opsional, di sini.
OUTER JOIN hadir dalam tiga rasa:
LEFT [ OUTER ] JOIN: Tabel kiri JOINungkapan ditambahkan ke gabungan seperti yang ditunjukkan di atas.
RIGHT [ OUTER ] JOIN: Tabel kanan JOINungkapan ditambahkan ke serikat seperti yang ditunjukkan di atas.
FULL [ OUTER ] JOIN: Kedua tabel JOINekspresi ditambahkan ke gabungan seperti yang ditunjukkan di atas.
Ada beberapa sintaks historis dan usang di Oracle dan SQL Server, yang OUTER JOINsudah mendukung sebelum standar SQL memiliki sintaks untuk ini:
-- OracleSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)AND fa.film_id = f.film_id(+)-- SQL ServerSELECT*FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id
Karena itu, jangan gunakan sintaks ini. Saya hanya daftar ini di sini sehingga Anda dapat mengenalinya dari posting blog lama / kode warisan.
Dipartisi OUTER JOIN
Beberapa orang tahu ini, tetapi standar SQL menentukan dipartisi OUTER JOIN(dan Oracle mengimplementasikannya). Anda dapat menulis hal-hal seperti ini:
WITH-- Using CONNECT BY to generate all dates in January
days(day)AS(SELECT DATE '2017-01-01'+ LEVEL -1FROM dual
CONNECTBY LEVEL <=31),-- Our departments
departments(department, created_at)AS(SELECT'Dept 1', DATE '2017-01-10'FROM dual UNIONALLSELECT'Dept 2', DATE '2017-01-11'FROM dual UNIONALLSELECT'Dept 3', DATE '2017-01-12'FROM dual UNIONALLSELECT'Dept 4', DATE '2017-04-01'FROM dual UNIONALLSELECT'Dept 5', DATE '2017-04-02'FROM dual
)SELECT*FROM days
LEFTJOIN departments
PARTITIONBY(department)-- This is where the magic happensON day >= created_at
Bagian dari hasil:
+--------+------------+------------+
| day | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1 | | -- Didn't match, but still get row
| Jan 02 | Dept 1 | | -- Didn't match, but still get row
| ... | Dept 1 | | -- Didn't match, but still get row
| Jan 09 | Dept 1 | | -- Didn't match, but still get row
| Jan 10 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 11 | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 12 | Dept 1 | Jan 10 | -- Matches, so get join result
| ... | Dept 1 | Jan 10 | -- Matches, so get join result
| Jan 31 | Dept 1 | Jan 10 | -- Matches, so get join result
Intinya di sini adalah bahwa semua baris dari sisi yang dipartisi dari gabungan akan berakhir di hasil terlepas jika JOINcocok dengan apa pun di "sisi lain dari GABUNG". Singkat cerita: Ini untuk mengisi data yang jarang dalam laporan. Sangat berguna!
SEMI BERGABUNG
Serius? Tidak ada jawaban lain yang mengerti? Tentu saja tidak, karena tidak memiliki sintaks asli dalam SQL, sayangnya (seperti ANTI GABUNG di bawah). Tetapi kita dapat menggunakan IN()dan EXISTS(), misalnya untuk menemukan semua aktor yang telah bermain dalam film:
SELECT*FROM actor a
WHEREEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
The WHERE a.actor_id = fa.actor_idpredikat bertindak sebagai semi bergabung predikat. Jika Anda tidak percaya, periksa rencana eksekusi, misalnya di Oracle. Anda akan melihat bahwa basis data mengeksekusi operasi SEMI GABUNG, bukan EXISTS()predikat.
SELECT*FROM actor a
WHERENOTEXISTS(SELECT*FROM film_actor fa
WHERE a.actor_id = fa.actor_id
)
Beberapa orang (terutama orang MySQL) juga menulis ANTI JOIN seperti ini:
SELECT*FROM actor a
LEFTJOIN film_actor fa
USING(actor_id)WHERE film_id ISNULL
Saya pikir alasan historisnya adalah kinerja.
GABUNGAN LATERAL
OMG, ini terlalu keren. Saya satu-satunya yang menyebutkannya? Inilah pertanyaan keren:
SELECT a.first_name, a.last_name, f.*FROM actor AS a
LEFTOUTERJOIN LATERAL (SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa USING(film_id)JOIN inventory AS i USING(film_id)JOIN rental AS r USING(inventory_id)JOIN payment AS p USING(rental_id)WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
ON true
Ini akan menemukan film TOP 5 penghasil pendapatan per aktor. Setiap kali Anda membutuhkan permintaan TOP-N-per-sesuatu, LATERAL JOINakan menjadi teman Anda. Jika Anda orang SQL Server, maka Anda tahu JOINjenis ini di bawah namaAPPLY
SELECT a.first_name, a.last_name, f.*FROM actor AS a
OUTERAPPLY(SELECT f.title, SUM(amount)AS revenue
FROM film AS f
JOIN film_actor AS fa ON f.film_id = fa.film_id
JOIN inventory AS i ON f.film_id = i.film_id
JOIN rental AS r ON i.inventory_id = r.inventory_id
JOIN payment AS p ON r.rental_id = p.rental_id
WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!GROUPBY f.film_id
ORDERBY revenue DESC
LIMIT 5)AS f
OK, mungkin itu curang, karena a LATERAL JOINatau APPLYekspresi benar-benar "subquery berkorelasi" yang menghasilkan beberapa baris. Tetapi jika kita mengizinkan "subqueries berkorelasi", kita juga dapat berbicara tentang ...
MULTISET
Ini hanya benar-benar diimplementasikan oleh Oracle dan Informix (setahu saya), tetapi dapat ditiru dalam PostgreSQL menggunakan array dan / atau XML dan di SQL Server menggunakan XML.
MULTISETmenghasilkan subquery yang berkorelasi dan menghasilkan kumpulan baris yang dihasilkan di kueri luar. Kueri di bawah ini memilih semua aktor dan untuk setiap aktor mengumpulkan film mereka dalam koleksi bersarang:
SELECT a.*, MULTISET (SELECT f.*FROM film AS f
JOIN film_actor AS fa USING(film_id)WHERE a.actor_id = fa.actor_id
)AS films
FROM actor
Seperti yang Anda lihat, ada lebih banyak jenis BERGABUNG dari sekedar "membosankan" INNER, OUTERdan CROSS JOINyang biasanya disebutkan. Lebih detail di artikel saya . Dan tolong, berhenti menggunakan diagram Venn untuk mengilustrasikannya.
Equijoin adalah kasus khusus dari theta-join di mana theta adalah kesetaraan. Theta-join adalah analog dengan kasus khusus dari join dalam di mana on adalah perbandingan theta pada kolom dari masing-masing. Beberapa dekade setelah Codd mendefinisikan mereka beberapa buku teks salah mendefinisikan theta join sebagai generalisasi yang merupakan analog dari inner join.
philipxy
@ philipxy: Ada yang spesifik yang harus saya ubah dalam jawaban saya? Anda dapat menyarankan hasil edit ...
Lukas Eder
10
Saya telah membuat ilustrasi yang menjelaskan lebih baik daripada kata-kata, menurut saya:
@Niraj Lingkaran A & B tidak mengandung baris A & B. Mereka disalin secara membabi buta dari tempat lain tanpa kredit. Gabung silang termasuk dalam kasus gabung dalam, itu gabung dalam pada 1 = 1. Dengan cara apa bagian-bagian gambar ini "sempurna"?
philipxy
@ philipxy Maaf tapi saya tidak terganggu jika disalin dari tempat lain. dan saya tidak yakin mana yang tidak benar pada gambar di atas. bagi saya ini tidak masalah. Gabung silang tidak dijelaskan di sini. Itu tidak termasuk dalam gabungan batin ..
Niraj
-3
Saya akan mendorong hewan peliharaan saya kesal: kata kunci PENGGUNAAN.
Jika kedua tabel di kedua sisi GABUNG memiliki kunci asing dengan benar dinamai (yaitu, nama yang sama, bukan hanya "id) maka ini dapat digunakan:
Apa
SQL JOIN
?SQL JOIN
adalah metode untuk mengambil data dari dua atau lebih tabel database.Apa perbedaannya
SQL JOIN
?Ada total lima
JOIN
s. Mereka :1. GABUNG atau GABUNGAN DALAM:
Dalam jenis a ini
JOIN
, kami mendapatkan semua catatan yang cocok dengan kondisi di kedua tabel, dan catatan di kedua tabel yang tidak cocok tidak dilaporkan.Dengan kata lain,
INNER JOIN
didasarkan pada fakta tunggal bahwa: HANYA entri yang cocok dalam KEDUA tabel HARUS dicantumkan.Perhatikan bahwa
JOIN
tanpa lainnyaJOIN
kata kunci (sepertiINNER
,OUTER
,LEFT
, dll) adalahINNER JOIN
. Dengan kata lain,JOIN
adalah gula sintaksis untukINNER JOIN
(lihat: Perbedaan antara BERGABUNG dan BERGABUNG DALAM ).2. GABUNG LUAR:
OUTER JOIN
mengambilEntah, baris yang cocok dari satu tabel dan semua baris di tabel lain Atau, semua baris di semua tabel (tidak masalah apakah ada kecocokan atau tidak).
Ada tiga jenis Outer Join:
2.1 BERGABUNG LEFT OUTER atau LEFT JOIN
Gabung ini mengembalikan semua baris dari tabel kiri bersamaan dengan baris yang cocok dari tabel kanan. Jika tidak ada kolom yang cocok di tabel kanan, itu mengembalikan
NULL
nilai.2.2 BERGABUNG DENGAN BENAR atau BERGABUNG KANAN
Ini
JOIN
mengembalikan semua baris dari tabel kanan bersamaan dengan baris yang cocok dari tabel kiri. Jika tidak ada kolom yang cocok di tabel sebelah kiri, itu mengembalikanNULL
nilai.2.3 BERGABUNG FULL OUTER atau FULL JOIN
Ini
JOIN
menggabungkanLEFT OUTER JOIN
danRIGHT OUTER JOIN
. Ini mengembalikan baris dari tabel mana pun ketika kondisi terpenuhi dan mengembalikanNULL
nilai ketika tidak ada kecocokan.Dengan kata lain,
OUTER JOIN
didasarkan pada kenyataan bahwa: HANYA entri yang cocok di SALAH SATU tabel (KANAN atau KIRI) atau KEDUA tabel (PENUH) HARUS dicantumkan.3. GABUNG ALAMI:
Ini didasarkan pada dua kondisi:
JOIN
dibuat pada semua kolom dengan nama yang sama untuk kesetaraan.Ini tampaknya lebih bersifat teoritis dan sebagai hasilnya (mungkin) sebagian besar DBMS bahkan tidak repot-repot mendukung ini.
4. LINTAS BERGABUNG:
Ini adalah produk Cartesian dari dua tabel yang terlibat. Hasil dari
CROSS JOIN
tidak akan masuk akal di sebagian besar situasi. Selain itu, kita tidak akan membutuhkan ini sama sekali (atau perlu paling tidak, tepatnya).5. BERGABUNG DIRI:
Ini bukan bentuk yang berbeda dari
JOIN
, melainkan merupakanJOIN
(INNER
,OUTER
, dll) dari meja untuk dirinya sendiri.GABUNG berdasarkan Operator
Bergantung pada operator yang digunakan untuk
JOIN
klausa, mungkin ada dua jenisJOIN
s. Mereka1. Equi BERGABUNG:
Untuk
JOIN
jenis apa pun (INNER
,,OUTER
dll), jika kita HANYA menggunakan operator persamaan (=), maka kita mengatakan bahwa ituJOIN
adalahEQUI JOIN
.2. Theta BERGABUNG:
Ini sama seperti
EQUI JOIN
tetapi memungkinkan semua operator lain seperti>, <,> = dll.sumber
Definisi:
BERGABUNG adalah cara untuk meminta data yang digabungkan bersama dari beberapa tabel secara bersamaan.
Jenis GABUNGAN:
Mengenai RDBMS ada 5 jenis gabungan:
Equi-Join: Menggabungkan catatan umum dari dua tabel berdasarkan kondisi kesetaraan. Secara teknis, Gabung dibuat dengan menggunakan operator kesetaraan (=) untuk membandingkan nilai-nilai Kunci Utama dari satu tabel dan nilai-nilai Kunci Asing dari tabel lain, maka set hasil mencakup catatan umum (cocok) dari kedua tabel. Untuk implementasi, lihat INNER-JOIN.
Natural-Join: Ini adalah versi yang disempurnakan dari Equi-Join, di mana operasi SELECT menghilangkan kolom duplikat. Untuk implementasi, lihat INNER-JOIN
Non-Equi-Join: Ini adalah kebalikan dari Equi-join di mana kondisi bergabung menggunakan selain dari operator yang sama (=) misalnya,! =, <=,> =, BETWEEN dll. Untuk implementasi, lihat INNER-JOIN.
Gabung Sendiri:: Perilaku bergabung yang disesuaikan di mana tabel dikombinasikan dengan dirinya sendiri; Ini biasanya diperlukan untuk menanyakan tabel referensi-sendiri (atau entitas hubungan Unary). Untuk implementasi, lihat INNER-JOINs.
Produk Cartesian: Ini lintas menggabungkan semua catatan dari kedua tabel tanpa kondisi apa pun. Secara teknis, ini mengembalikan set hasil kueri tanpa WHERE-Clause.
Sehubungan dengan kepedulian dan kemajuan SQL, ada 3 jenis gabungan dan semua gabungan RDBMS dapat dicapai dengan menggunakan jenis gabungan ini.
INNER-JOIN: Menggabungkan (atau menggabungkan) baris yang cocok dari dua tabel. Pencocokan dilakukan berdasarkan kolom umum tabel dan operasi pembandingannya. Jika kondisi berdasarkan kesetaraan maka: EQUI-JOIN dilakukan, jika tidak Non-EQUI-Bergabung.
OUTER-JOIN: Menggabungkan (atau menggabungkan) baris yang cocok dari dua tabel dan baris yang tidak cocok dengan nilai NULL. Namun, dapat mengkustomisasi pemilihan baris yang tidak cocok misalnya, memilih baris yang tidak cocok dari tabel pertama atau tabel kedua berdasarkan sub-tipe: LEFT OUTER JOIN dan RIGHT OUTER JOIN.
2.1. LEFT Outer JOIN (alias, LEFT-JOIN): Mengembalikan baris yang cocok dari dua tabel dan tidak cocok dengan tabel LEFT (yaitu, tabel pertama).
2.2. RIGHT Outer JOIN (alias, RIGHT-JOIN): Mengembalikan baris yang cocok dari dua tabel dan tidak cocok dengan tabel RIGHT saja.
2.3. FULL OUTER JOIN (alias OUTER JOIN): Pengembalian cocok dan tidak cocok dari kedua tabel.
GABUNG-GABUNG: Gabung ini tidak menggabungkan / menggabungkan melainkan melakukan produk Cartesian.
Catatan: Self-JOIN dapat diraih oleh INNER-JOIN, OUTER-JOIN dan CROSS-JOIN berdasarkan persyaratan tetapi tabel harus bergabung dengan dirinya sendiri.
Untuk informasi lebih lanjut:
Contoh:
1.1: INNER-JOIN: Implementasi Equi-join
1.2: INNER-JOIN: Implementasi Natural-JOIN
1.3: INNER-JOIN dengan implementasi NON-Equi-join
1.4: INNER-JOIN dengan DIRI-JOIN
2.1: OUTER JOIN (gabung luar penuh)
2.2: KIRI BERGABUNG
2.3: BERGABUNG DENGAN BENAR
3.1: LINTAS BERGABUNG
3.2: CROSS JOIN-Self JOIN
//ATAU//
sumber
intersect
/except
/union
; di sini lingkaran adalah baris yang dikembalikan olehleft
&right
join
, seperti yang dikatakan label bernomor. Gambar AXB adalah omong kosong.cross join
=inner join on 1=1
& adalah kasus khusus dari diagram pertama.UNION JOIN
. Sekarang dibuat usang dalam SQL: 2003.Menariknya, sebagian besar jawaban lain menderita dua masalah ini:
Saya baru-baru ini menulis sebuah artikel tentang topik ini: Sebuah Panduan Komprehensif yang Mungkin Tidak Lengkap untuk Berbagai Cara untuk BERGABUNG Tabel dalam SQL , yang akan saya ringkas di sini.
Pertama dan terpenting: GABUNG adalah produk kartesius
Inilah sebabnya mengapa diagram Venn menjelaskannya secara tidak akurat, karena JOIN membuat produk kartesius di antara dua tabel yang digabungkan. Wikipedia menggambarkannya dengan baik:
Sintaks SQL untuk produk kartesius adalah
CROSS JOIN
. Sebagai contoh:Yang menggabungkan semua baris dari satu tabel dengan semua baris dari tabel lainnya:
Sumber:
Hasil:
Jika kita hanya menulis daftar tabel yang dipisahkan koma, kita akan mendapatkan yang sama:
INNER JOIN (Theta-JOIN)
An
INNER JOIN
hanya disaring diCROSS JOIN
mana predikat filter disebutTheta
dalam aljabar relasional.Misalnya:
Perhatikan bahwa kata kunci
INNER
adalah opsional (kecuali dalam MS Access).( lihat artikel untuk contoh hasil )
EQUI BERGABUNG
Jenis khusus Theta-JOIN adalah equi JOIN, yang paling sering kita gunakan. Predikat bergabung dengan kunci utama dari satu tabel dengan kunci asing dari tabel lain. Jika kita menggunakan database Sakila untuk ilustrasi, kita dapat menulis:
Ini menggabungkan semua aktor dengan film mereka.
Atau juga, pada beberapa database:
The
USING()
sintaks memungkinkan untuk menentukan kolom yang harus hadir di kedua sisi dari BERGABUNG meja operasi dan menciptakan predikat kesetaraan pada dua kolom.GABUNG ALAMI
Jawaban lain telah mencantumkan "tipe GABUNG" ini secara terpisah, tetapi itu tidak masuk akal. Ini hanya bentuk gula sintaksis untuk equi JOIN, yang merupakan kasus khusus dari Theta-JOIN atau INNER JOIN. GABUNG ALAMI hanya mengumpulkan semua kolom yang umum untuk kedua tabel yang bergabung dan bergabung
USING()
dengan kolom tersebut. Yang hampir tidak pernah berguna, karena kecocokan yang tidak disengaja (sepertiLAST_UPDATE
kolom dalam database Sakila ).Inilah sintaksinya:
OUTER BERGABUNG
Sekarang,
OUTER JOIN
sedikit berbeda dariINNER JOIN
karena ia menciptakanUNION
beberapa produk kartesius. Kita bisa menulis:Tidak ada yang mau menulis yang terakhir, jadi kami menulis
OUTER JOIN
(yang biasanya lebih baik dioptimalkan oleh basis data).Seperti
INNER
, kata kunciOUTER
bersifat opsional, di sini.OUTER JOIN
hadir dalam tiga rasa:LEFT [ OUTER ] JOIN
: Tabel kiriJOIN
ungkapan ditambahkan ke gabungan seperti yang ditunjukkan di atas.RIGHT [ OUTER ] JOIN
: Tabel kananJOIN
ungkapan ditambahkan ke serikat seperti yang ditunjukkan di atas.FULL [ OUTER ] JOIN
: Kedua tabelJOIN
ekspresi ditambahkan ke gabungan seperti yang ditunjukkan di atas.Semua ini dapat dikombinasikan dengan kata kunci
USING()
atau denganNATURAL
( Saya benar-benar memiliki kasus penggunaan dunia nyata untukNATURAL FULL JOIN
baru - baru ini )Sintaks alternatif
Ada beberapa sintaks historis dan usang di Oracle dan SQL Server, yang
OUTER JOIN
sudah mendukung sebelum standar SQL memiliki sintaks untuk ini:Karena itu, jangan gunakan sintaks ini. Saya hanya daftar ini di sini sehingga Anda dapat mengenalinya dari posting blog lama / kode warisan.
Dipartisi
OUTER JOIN
Beberapa orang tahu ini, tetapi standar SQL menentukan dipartisi
OUTER JOIN
(dan Oracle mengimplementasikannya). Anda dapat menulis hal-hal seperti ini:Bagian dari hasil:
Intinya di sini adalah bahwa semua baris dari sisi yang dipartisi dari gabungan akan berakhir di hasil terlepas jika
JOIN
cocok dengan apa pun di "sisi lain dari GABUNG". Singkat cerita: Ini untuk mengisi data yang jarang dalam laporan. Sangat berguna!SEMI BERGABUNG
Serius? Tidak ada jawaban lain yang mengerti? Tentu saja tidak, karena tidak memiliki sintaks asli dalam SQL, sayangnya (seperti ANTI GABUNG di bawah). Tetapi kita dapat menggunakan
IN()
danEXISTS()
, misalnya untuk menemukan semua aktor yang telah bermain dalam film:The
WHERE a.actor_id = fa.actor_id
predikat bertindak sebagai semi bergabung predikat. Jika Anda tidak percaya, periksa rencana eksekusi, misalnya di Oracle. Anda akan melihat bahwa basis data mengeksekusi operasi SEMI GABUNG, bukanEXISTS()
predikat.ANTI BERGABUNG
Ini adalah kebalikan dari SEMI BERGABUNG ( hati-hati untuk tidak menggunakan
NOT IN
meskipun , karena memiliki peringatan penting)Berikut adalah semua aktor tanpa film:
Beberapa orang (terutama orang MySQL) juga menulis ANTI JOIN seperti ini:
Saya pikir alasan historisnya adalah kinerja.
GABUNGAN LATERAL
OMG, ini terlalu keren. Saya satu-satunya yang menyebutkannya? Inilah pertanyaan keren:
Ini akan menemukan film TOP 5 penghasil pendapatan per aktor. Setiap kali Anda membutuhkan permintaan TOP-N-per-sesuatu,
LATERAL JOIN
akan menjadi teman Anda. Jika Anda orang SQL Server, maka Anda tahuJOIN
jenis ini di bawah namaAPPLY
OK, mungkin itu curang, karena a
LATERAL JOIN
atauAPPLY
ekspresi benar-benar "subquery berkorelasi" yang menghasilkan beberapa baris. Tetapi jika kita mengizinkan "subqueries berkorelasi", kita juga dapat berbicara tentang ...MULTISET
Ini hanya benar-benar diimplementasikan oleh Oracle dan Informix (setahu saya), tetapi dapat ditiru dalam PostgreSQL menggunakan array dan / atau XML dan di SQL Server menggunakan XML.
MULTISET
menghasilkan subquery yang berkorelasi dan menghasilkan kumpulan baris yang dihasilkan di kueri luar. Kueri di bawah ini memilih semua aktor dan untuk setiap aktor mengumpulkan film mereka dalam koleksi bersarang:Seperti yang Anda lihat, ada lebih banyak jenis BERGABUNG dari sekedar "membosankan"
INNER
,OUTER
danCROSS JOIN
yang biasanya disebutkan. Lebih detail di artikel saya . Dan tolong, berhenti menggunakan diagram Venn untuk mengilustrasikannya.sumber
Saya telah membuat ilustrasi yang menjelaskan lebih baik daripada kata-kata, menurut saya:
sumber
Saya akan mendorong hewan peliharaan saya kesal: kata kunci PENGGUNAAN.
Jika kedua tabel di kedua sisi GABUNG memiliki kunci asing dengan benar dinamai (yaitu, nama yang sama, bukan hanya "id) maka ini dapat digunakan:
Saya menemukan ini sangat praktis, mudah dibaca, dan tidak cukup sering digunakan.
sumber