Juga bagaimana LEFT JOIN
, RIGHT JOIN
dan FULL JOIN
cocok?
Juga bagaimana LEFT JOIN
, RIGHT JOIN
dan FULL JOIN
cocok?
Jawaban:
Dengan asumsi Anda bergabung di kolom tanpa duplikat, yang merupakan kasus yang sangat umum:
Sambungan dalam dari A dan B memberikan hasil dari A berpotongan B, yaitu bagian dalam dari persimpangan diagram Venn .
Gabungan luar dari A dan B memberikan hasil dari serikat A B, yaitu bagian luar dari serikat diagram Venn.
Contohnya
Misalkan Anda memiliki dua tabel, masing-masing dengan satu kolom, dan data sebagai berikut:
A B
- -
1 3
2 4
3 5
4 6
Perhatikan bahwa (1,2) adalah unik untuk A, (3,4) adalah umum, dan (5,6) unik untuk B.
Batin bergabung
Gabungan dalam menggunakan salah satu kueri yang setara memberikan persimpangan dua tabel, yaitu dua baris yang sama-sama mereka miliki.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
a | b
--+--
3 | 3
4 | 4
Gabung luar kiri
Gabung luar kiri akan memberikan semua baris dalam A, ditambah baris umum dalam B.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
Gabung luar kanan
Gabung luar kanan akan memberikan semua baris dalam B, ditambah baris umum dalam A.
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
Gabung luar penuh
Gabungan luar penuh akan memberi Anda gabungan A dan B, yaitu semua baris dalam A dan semua baris dalam B. Jika sesuatu dalam A tidak memiliki datum yang sesuai dalam B, maka bagian B adalah nol, dan sebaliknya sebaliknya.
select * from a FULL OUTER JOIN b on a.a = b.b;
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
Diagram Venn tidak benar-benar melakukannya untuk saya.
Mereka tidak menunjukkan perbedaan antara gabungan silang dan gabungan internal, misalnya, atau lebih umum menunjukkan perbedaan antara berbagai jenis predikat gabungan atau menyediakan kerangka kerja untuk alasan tentang bagaimana mereka akan beroperasi.
Tidak ada pengganti untuk memahami pemrosesan logis dan relatif mudah dipahami.
on
klausa terhadap semua baris dari langkah 1 menjaga mereka di mana predikat dievaluasitrue
(NB: Dalam praktiknya pengoptimal kueri dapat menemukan cara yang lebih efisien untuk mengeksekusi kueri daripada uraian yang murni logis di atas tetapi hasil akhirnya harus sama)
Saya akan mulai dengan versi animasi dari gabungan luar penuh . Penjelasan lebih lanjut berikut.
Tabel Sumber
Pertama mulai dengan CROSS JOIN
(Produk Cartesian AKA). Ini tidak memiliki ON
klausa dan hanya mengembalikan setiap kombinasi baris dari dua tabel.
PILIH A. Warna, B. Warna DARI LINTAS BERGABUNG B
Gabungan dalam dan luar memiliki predikat klausa "ON".
PILIH A. Warna, B. Warna DARI DALAM BATIN GABUNG B PADA A. Warna = B. Warna
Di atas adalah equi gabung klasik.
Kondisi sambungan dalam tidak harus berupa kondisi persamaan dan tidak perlu referensi kolom dari kedua (atau bahkan salah satu) dari tabel. Mengevaluasi A.Colour NOT IN ('Green','Blue')
pada setiap baris salib bergabung dengan pengembalian.
PILIH A. Warna, B. Warna DARI DALAM BATIN GABUNG B ON 1 = 1
Kondisi gabungan dievaluasi benar untuk semua baris dalam hasil gabungan silang, jadi ini sama dengan gabungan silang. Saya tidak akan mengulangi gambar 16 baris lagi.
Gabungan Luar dievaluasi secara logis dengan cara yang sama dengan gabungan dalam kecuali bahwa jika satu baris dari tabel kiri (untuk gabungan kiri) tidak bergabung dengan baris apa pun dari tabel sebelah kanan sama sekali dipertahankan dalam hasil dengan NULL
nilai untuk kolom tangan kanan.
Ini hanya membatasi hasil sebelumnya hanya mengembalikan baris di mana B.Colour IS NULL
. Dalam kasus khusus ini, ini akan menjadi baris yang dipertahankan karena mereka tidak memiliki kecocokan di tabel sebelah kanan dan kueri mengembalikan baris merah tunggal yang tidak cocok dalam tabel B
. Ini dikenal sebagai anti semi join.
Penting untuk memilih kolom untuk IS NULL
pengujian yang tidak dapat dibatalkan atau untuk kondisi gabungan memastikan bahwa NULL
nilai apa pun akan dikecualikan agar pola ini berfungsi dengan benar dan menghindari hanya mengembalikan baris yang kebetulan memiliki NULL
nilai untuk itu kolom di samping baris yang tidak cocok.
Gabungan luar kanan bertindak serupa dengan gabungan luar kiri kecuali mereka mempertahankan baris yang tidak cocok dari tabel kanan dan null memperpanjang kolom sebelah kiri.
Gabungan luar penuh menggabungkan perilaku gabungan kiri dan kanan dan mempertahankan baris yang tidak cocok dari tabel kiri dan kanan.
Tidak ada baris dalam tanda silang yang cocok dengan 1=0
predikat. Semua baris dari kedua sisi dipertahankan menggunakan aturan join luar normal dengan NULL di kolom dari tabel di sisi lainnya.
Dengan sedikit perubahan pada kueri sebelumnya, orang dapat mensimulasikan satu UNION ALL
dari dua tabel.
Perhatikan bahwa WHERE
klausa (jika ada) secara logis berjalan setelah bergabung. Salah satu kesalahan umum adalah melakukan gabungan luar kiri dan kemudian memasukkan klausa WHERE dengan kondisi di tabel kanan yang berakhir tidak termasuk baris yang tidak cocok. Di atas akhirnya melakukan gabungan luar ...
... Dan kemudian klausa "Di mana" berjalan. NULL= 'Green'
tidak mengevaluasi ke true sehingga baris yang diawetkan oleh sambungan luar berakhir dibuang (bersama dengan yang biru) secara efektif mengubah sambungan kembali ke yang dalam.
Jika maksudnya hanya menyertakan baris dari B di mana Warna adalah Hijau dan semua baris dari A terlepas dari sintaks yang benar akan menjadi
Lihat contoh-contoh ini dijalankan langsung di SQLFiddle.com .
Bergabung digunakan untuk menggabungkan data dari dua tabel, dengan hasil menjadi tabel sementara yang baru. Bergabung dilakukan berdasarkan sesuatu yang disebut predikat, yang menentukan kondisi yang digunakan untuk melakukan gabungan. Perbedaan antara gabungan dalam dan gabungan luar adalah bahwa gabungan dalam akan mengembalikan hanya baris yang benar-benar cocok berdasarkan predikat bergabung. Untuk eg- Mari kita pertimbangkan tabel Karyawan dan Lokasi:
Gabung Dalam: - Gabung dalam menciptakan tabel hasil baru dengan menggabungkan nilai kolom dua tabel ( Karyawan dan Lokasi ) berdasarkan predikat gabung. Kueri membandingkan setiap baris Karyawan dengan setiap baris Lokasi untuk menemukan semua pasangan baris yang memenuhi predikat gabungan. Ketika predikat gabungan dipenuhi dengan mencocokkan nilai-nilai non-NULL, nilai-nilai kolom untuk setiap pasangan baris yang cocok dari Karyawan dan Lokasi digabungkan menjadi baris hasil. Inilah yang akan terlihat seperti SQL untuk gabungan dalam:
select * from employee inner join location on employee.empID = location.empID
OR
select * from employee, location where employee.empID = location.empID
Sekarang, inilah hasil dari menjalankan SQL akan terlihat seperti:
Gabung Luar: - Gabung luar tidak mengharuskan setiap catatan dalam dua tabel yang digabungkan untuk memiliki catatan yang cocok. Tabel yang digabungkan mempertahankan setiap catatan — bahkan jika tidak ada catatan yang cocok lainnya. Gabungan luar membagi lebih jauh menjadi gabungan luar kiri dan gabungan luar kanan, tergantung pada baris tabel mana yang dipertahankan (kiri atau kanan).
Gabung Luar Kiri: - Hasil gabung luar kiri (atau gabung kiri saja) untuk tabel Karyawan dan Lokasi selalu berisi semua catatan tabel "kiri" ( Karyawan ), bahkan jika kondisi gabung tidak menemukan catatan yang cocok di tabel "kanan" ( Lokasi ). Berikut ini tampilannya SQL untuk gabungan luar kiri, menggunakan tabel di atas:
select * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Sekarang, inilah hasil dari menjalankan SQL ini akan terlihat seperti:
Gabung Luar Kanan: - Gabung luar kanan (atau gabung kanan) sangat menyerupai gabung luar kiri, kecuali dengan perlakuan tabel terbalik. Setiap baris dari tabel "kanan" ( Lokasi ) akan muncul di tabel yang digabungkan setidaknya satu kali. Jika tidak ada baris yang cocok dari tabel "kiri" ( Karyawan ), NULL akan muncul di kolom dari Karyawan untuk catatan yang tidak memiliki kecocokan di Lokasi . Seperti inilah tampilan SQL:
select * from employee right outer join location on employee.empID = location.empID;
//Use of outer keyword is optional
Dengan menggunakan tabel di atas, kita dapat menunjukkan seperti apa hasil dari gabungan luar kanan akan terlihat seperti:
Gabungan Luar Penuh: - Full Outer Join atau Full Join adalah untuk mempertahankan informasi yang tidak cocok dengan memasukkan baris yang tidak cocok dalam hasil sambungan, gunakan gabungan luar penuh. Ini mencakup semua baris dari kedua tabel, terlepas dari apakah tabel lain memiliki nilai yang cocok atau tidak.
Ambil baris yang cocok saja, yaitu A intersect B
,.
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Pilih semua catatan dari tabel pertama, dan semua catatan di tabel kedua yang cocok dengan kunci yang digabungkan.
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Pilih semua catatan dari tabel kedua, dan semua catatan di tabel pertama yang cocok dengan kunci yang digabungkan.
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
Dengan kata sederhana:
Sebuah bergabung dalam mengambil baris cocok saja.
Sedangkan gabungan luar mengambil baris yang cocok dari satu tabel dan semua baris di tabel lain .... hasilnya tergantung pada yang Anda gunakan:
Kiri : Baris yang cocok di tabel kanan dan semua baris di tabel kiri
Kanan : Baris yang cocok di tabel kiri dan semua baris di tabel kanan atau
Lengkap : Semua baris di semua tabel. Tidak masalah apakah ada kecocokan atau tidak
Gabung bagian dalam hanya menampilkan baris jika ada catatan yang cocok di sisi gabung lainnya (kanan).
Gabungan luar (kiri) menunjukkan baris untuk setiap catatan di sisi kiri, bahkan jika tidak ada baris yang cocok di sisi lainnya (kanan) gabungan. Jika tidak ada baris yang cocok, kolom untuk sisi lain (kanan) akan menampilkan NULLs.
Gabungan dalam mengharuskan catatan dengan ID terkait ada di tabel bergabung.
Gabungan luar akan mengembalikan catatan untuk sisi kiri bahkan jika tidak ada yang ada untuk sisi kanan.
Misalnya, Anda memiliki tabel Pesanan dan Tabel Pesan. Mereka terkait oleh "OrderID".
Pesanan
Detail pesanan
Permintaan
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
INNER JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
hanya akan mengembalikan Pesanan yang juga memiliki sesuatu di tabel OrderDetails.
Jika Anda mengubahnya menjadi OUTER LEFT JOIN
SELECT Orders.OrderID, Orders.CustomerName
FROM Orders
LEFT JOIN OrderDetails
ON Orders.OrderID = OrderDetails.OrderID
maka itu akan mengembalikan catatan dari tabel Pesanan bahkan jika mereka tidak memiliki catatan OrderDetails.
Anda dapat menggunakan ini untuk menemukan Pesanan yang tidak memiliki OrderDetail yang menunjukkan kemungkinan pesanan yatim dengan menambahkan klausa di mana seperti WHERE OrderDetails.OrderID IS NULL
.
SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c, categories_description cd WHERE c.id = cd.categories_id AND c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
ke SELECT c.id, c.status, cd.name, c.parent_id, cd.description, c.image FROM categories c INNER JOIN categories_description cd ON c.id = cd.categories_id WHERE c.status = 1 AND cd.language_id = 2 ORDER BY c.parent_id ASC
(MySQL) dengan sukses. Saya tidak yakin tentang kondisi tambahan, mereka bercampur dengan baik ...
Dengan kata sederhana:
Batin bergabung -> HANYA HANYA catatan umum dari tabel induk dan anak DI MANA kunci utama tabel Induk cocok dengan kunci Asing di tabel Anak.
Kiri gabung ->
kode semu
1.Take All records from left Table
2.for(each record in right table,) {
if(Records from left & right table matching on primary & foreign key){
use their values as it is as result of join at the right side for 2nd table.
} else {
put value NULL values in that particular record as result of join at the right side for 2nd table.
}
}
Bergabunglah dengan benar : Bertolak belakang dengan gabung kiri. Letakkan nama tabel di LEFT JOIN di sebelah kanan di Right join, Anda mendapatkan output yang sama dengan LEFT JOIN.
Gabungan luar : Tampilkan semua catatan di kedua tabelNo matter what
. Jika catatan di tabel kiri tidak cocok dengan tabel kanan berdasarkan pada primer, kunci Forieign, gunakan nilai NULL sebagai hasil dari bergabung.
Contoh:
Mari kita asumsikan sekarang untuk 2 tabel
1.employees , 2.phone_numbers_employees
employees : id , name
phone_numbers_employees : id , phone_num , emp_id
Di sini, tabel karyawan adalah tabel Master, phone_numbers_employees adalah tabel anak (ini berisi emp_id
kunci asing yang menghubungkan employee.id
tabel anak-nya.)
Bergabung batin
Catat 2 tabel HANYA JIKA Kunci utama tabel karyawan (ID-nya) cocok dengan kunci Asing dari tabel Anak phone_numbers_employees (emp_id) .
Jadi kueri akan menjadi:
SELECT e.id , e.name , p.phone_num FROM employees AS e INNER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Di sini, ambil hanya baris yang cocok pada kunci primer = kunci asing seperti yang dijelaskan di atas. Di sini baris yang tidak cocok pada kunci primer = kunci asing dilewati sebagai hasil penggabungan.
Gabungan kiri :
Gabung kiri mempertahankan semua baris tabel kiri, terlepas dari apakah ada baris yang cocok di tabel kanan.
SELECT e.id , e.name , p.phone_num FROM employees AS e LEFT JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Gabungan luar :
SELECT e.id , e.name , p.phone_num FROM employees AS e OUTER JOIN phone_numbers_employees AS p ON e.id = p.emp_id;
Secara diagram terlihat seperti:
Kau gunakan INNER JOIN
untuk mengembalikan semua baris dari kedua tabel di mana ada kecocokan. yaitu Dalam tabel yang dihasilkan semua baris dan kolom akan memiliki nilai.
Di OUTER JOIN
tabel yang dihasilkan mungkin memiliki kolom kosong. Gabung luar bisa berupa LEFT
atau RIGHT
.
LEFT OUTER JOIN
mengembalikan semua baris dari tabel pertama, bahkan jika tidak ada kecocokan di tabel kedua.
RIGHT OUTER JOIN
mengembalikan semua baris dari tabel kedua, bahkan jika tidak ada kecocokan di tabel pertama.
Ini adalah penjelasan diagram yang baik untuk semua jenis sambungan
sumber: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOIN
mensyaratkan setidaknya ada kecocokan dalam membandingkan dua tabel. Misalnya, tabel A dan tabel B yang menyiratkan A ٨ B (persimpangan B).
LEFT OUTER JOIN
dan LEFT JOIN
sama. Ini memberikan semua catatan yang cocok di kedua tabel dan semua kemungkinan di tabel kiri.
Demikian pula, RIGHT OUTER JOIN
dan RIGHT JOIN
sama. Ini memberikan semua catatan yang cocok di kedua tabel dan semua kemungkinan dari tabel yang tepat.
FULL JOIN
adalah kombinasi dari LEFT OUTER JOIN
dan RIGHT OUTER JOIN
tanpa duplikasi.
Jawabannya adalah dalam arti masing-masing, demikian juga dalam hasilnya.
Catatan:
DiSQLite
tidak adaRIGHT OUTER JOIN
atauFULL OUTER JOIN
.
Dan juga diMySQL
sana tidak adaFULL OUTER JOIN
.
Jawaban saya didasarkan pada Catatan di atas .
Ketika Anda memiliki dua tabel seperti ini:
--[table1] --[table2]
id | name id | name
---+------- ---+-------
1 | a1 1 | a2
2 | b1 3 | b2
CROSS JOIN / OUTER JOIN:
Anda dapat memiliki semua data tabel dengan CROSS JOIN
atau hanya dengan ,
seperti ini:
SELECT * FROM table1, table2
--[OR]
SELECT * FROM table1 CROSS JOIN table2
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
1 | a1 | 3 | b2
2 | b1 | 1 | a2
2 | b1 | 3 | b2
INNER JOIN:
Ketika Anda ingin menambahkan filter ke hasil di atas berdasarkan pada relasi seperti table1.id = table2.id
yang dapat Anda gunakan INNER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
--[OR]
SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+----+------
1 | a1 | 1 | a2
LEFT [OUTER] GABUNG:
Ketika Anda ingin memiliki semua baris dari salah satu tabel di hasil di atas - dengan hubungan yang sama - Anda dapat menggunakan LEFT JOIN
:
(Untuk KANAN BERGABUNG hanya mengubah tempat tabel)
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
--[OR]
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
--[Results:]
id | name | id | name
---+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
FULL OUTER JOIN:
Ketika Anda juga ingin memiliki semua baris tabel lain dalam hasil Anda, Anda dapat menggunakan FULL OUTER JOIN
:
SELECT * FROM table1, table2 WHERE table1.id = table2.id
UNION ALL
SELECT *, Null, Null FROM table1 WHERE Not table1.id In (SELECT id FROM table2)
UNION ALL
SELECT Null, Null, * FROM table2 WHERE Not table2.id In (SELECT id FROM table1)
--[OR] (recommended for SQLite)
SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id
UNION ALL
SELECT * FROM table2 LEFT JOIN table1 ON table2.id = table1.id
WHERE table1.id IS NULL
--[OR]
SELECT * FROM table1 FULL OUTER JOIN table2 On table1.id = table2.id
--[Results:]
id | name | id | name
-----+------+------+------
1 | a1 | 1 | a2
2 | b1 | Null | Null
Null | Null | 3 | b2
Nah, sesuai kebutuhan Anda, Anda memilih masing-masing yang memenuhi kebutuhan Anda;).
full outer join
di MySQL juga.
Batin bergabung.
Gabung menggabungkan baris dari dua tabel. Gabungan dalam mencoba untuk mencocokkan dua tabel berdasarkan kriteria yang Anda tentukan dalam kueri, dan hanya mengembalikan baris yang cocok. Jika satu baris dari tabel pertama dalam gabungan cocok dengan dua baris di tabel kedua, maka dua baris akan dikembalikan dalam hasil. Jika ada baris di tabel pertama yang tidak cocok dengan baris di yang kedua, itu tidak dikembalikan; juga, jika ada baris di tabel kedua yang tidak cocok dengan baris di yang pertama, itu tidak dikembalikan.
Outer Join.
Sebuah meninggalkan bergabung upaya untuk menemukan cocok baris dari tabel pertama yang baris dalam tabel kedua. Jika tidak dapat menemukan kecocokan, itu akan mengembalikan kolom dari tabel pertama dan membiarkan kolom dari tabel kedua kosong (nol).
INNER JOIN
paling umum bergabung untuk dua atau lebih tabel. Ini mengembalikan data yang cocok pada kedua tabel pada relung primer dan relung meja.OUTER JOIN
sama dengan INNER JOIN
, tetapi juga termasuk NULL
data di ResultSet.
LEFT JOIN
= INNER JOIN
+ Data yang tidak cocok dari tabel kiri dengan Null
kecocokan di tabel kanan.RIGHT JOIN
= INNER JOIN
+ Data yang tidak cocok dari tabel kanan dengan Null
kecocokan di tabel kiri.FULL JOIN
= INNER JOIN
+ Data yang tidak cocok pada tabel kanan dan kiri dengan Null
kecocokan.INNER JOIN
dan OUTER JOIN
kita dapat menulis permintaan bergabung sendiri.Sebagai contoh:
SELECT *
FROM tablea a
INNER JOIN tableb b
ON a.primary_key = b.foreign_key
INNER JOIN tablec c
ON b.primary_key = c.foreign_key
Saya tidak melihat banyak detail tentang kinerja dan pengoptimal dalam jawaban lain.
Terkadang hanya baik untuk mengetahui hal itu INNER JOIN
asosiatif yang berarti pengoptimal memiliki opsi paling banyak untuk bermain dengannya. Itu dapat menyusun ulang urutan bergabung untuk membuatnya lebih cepat menjaga hasil yang sama. Pengoptimal dapat menggunakan mode bergabung paling banyak.
Secara umum, ini adalah praktik yang baik untuk mencoba menggunakan INNER JOIN
alih-alih berbagai jenis sambungan. (Tentu saja jika mungkin mempertimbangkan hasil yang diharapkan ditetapkan.)
Ada beberapa contoh dan penjelasan yang baik di sini tentang perilaku asosiatif yang aneh ini:
INNER JOIN
lebih lambat daripada LEFT JOIN
di sebagian besar waktu, Dan orang dapat menggunakan LEFT JOIN
alih-alih INNER JOIN
dengan menambahkan WHERE
untuk menghapus NULL
hasil yang tidak terduga ;).
INNER
lebih lambat?
Setelah mengkritik diagram Venn berbayang merah yang sangat digemari, saya pikir hanya adil untuk memposting upaya saya sendiri.
Meskipun jawaban @Martin Smith adalah yang terbaik dari banyak ini dengan cara yang panjang, hanya menunjukkan kolom kunci dari setiap tabel, sedangkan saya pikir idealnya kolom non-kunci juga harus ditampilkan.
Yang terbaik yang bisa saya lakukan dalam waktu setengah jam diperbolehkan, saya masih tidak berpikir itu cukup menunjukkan bahwa nol ada di sana karena tidak adanya nilai-nilai kunci dalam TableB
atau yang OUTER JOIN
sebenarnya merupakan persatuan daripada gabungan:
TableA a LEFT OUTER JOIN TableB b
denganTableB B RIGHT OUTER JOIN TableA a
Algoritma yang tepat untuk INNER JOIN
, LEFT/RIGHT OUTER JOIN
adalah sebagai berikut:
a
(a, b[i])
ON ...
klausa terhadap setiap pasangan:ON( a, b[i] ) = true/false?
true
, kembalikan baris gabungan itu (a, b[i])
.Outer Join
lalu kembalikan pasangan (virtual) yang digunakan Null
untuk semua kolom dari tabel lain: (a, Null)
untuk join luar LEFT atau (Null, b)
untuk join luar KANAN. Ini untuk memastikan semua baris tabel pertama ada di hasil akhir.Catatan: kondisi yang ditentukan dalam ON
klausa bisa apa saja, tidak diharuskan menggunakan Kunci Utama (dan Anda tidak perlu selalu merujuk ke Kolom dari kedua tabel)! Sebagai contoh:
... ON T1.title = T2.title AND T1.version < T2.version
(=> lihat posting ini sebagai contoh penggunaan: Pilih hanya baris dengan nilai maksimal pada kolom )... ON T1.y IS NULL
... ON 1 = 0
(seperti sampel)Catatan: Gabung Kiri = Gabung Kiri Luar, Gabung Kanan = Gabung Luar Kanan.
Definisi Paling Sederhana
Inner Join: Mengembalikan catatan yang cocok dari kedua tabel.
Full Outer Join: Mengembalikan catatan yang cocok dan tidak cocok dari kedua tabel dengan nol untuk catatan yang tidak cocok dari Kedua Tabel .
Kiri Luar Gabung: Mengembalikan catatan yang cocok dan tidak cocok hanya dari tabel di Sisi Kiri .
Right Outer Join: Mengembalikan catatan yang cocok dan tidak cocok hanya dari tabel di Sisi Kanan .
Pendeknya
Cocok + Kiri Tak Tertandingi + Kanan Tidak Tertandingi = Gabung Luar Penuh
Cocok + Kiri Tidak Cocok = Kiri Luar Gabung
Cocok + Right Unmatched = Right Outer Join
Cocok = Bergabung Gabung
Dalam Ketentuan Sederhana,
1. INNER JOIN ATAU EQUI JOIN: Mengembalikan resultset yang hanya cocok dengan kondisi di kedua tabel.
2. OUTER JOIN: Mengembalikan resultset semua nilai dari kedua tabel meskipun ada kondisi yang cocok atau tidak.
3. LEFT JOIN: Mengembalikan resultset semua nilai dari tabel kiri dan hanya baris yang cocok dengan kondisi di tabel kanan.
4. KANAN BERGABUNG: Mengembalikan resultset semua nilai dari tabel kanan dan hanya baris yang cocok dengan kondisi di tabel kiri.
5. GABUNGAN LENGKAP: Gabung Penuh dan Gabung Luar Penuh sama.
Contohnya
Misalkan Anda memiliki dua tabel, masing-masing dengan satu kolom, dan data sebagai berikut:
A B
- -
1 3
2 4
3 5
4 6
7
8
Perhatikan bahwa (1,2,7,8) adalah unik untuk A, (3,4) adalah umum, dan (5,6) unik untuk B.
Kata kunci INNER JOIN memilih semua baris dari kedua tabel selama kondisinya memuaskan. Kata kunci ini akan membuat hasil-set dengan menggabungkan semua baris dari kedua tabel di mana kondisi terpenuhi yaitu nilai bidang umum akan sama.
select * from a INNER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b;
Hasil:
a | b
--+--
3 | 3
4 | 4
Gabung ini mengembalikan semua baris tabel di sisi kiri gabung dan baris yang cocok untuk tabel di sisi kanan gabung. Baris yang tidak ada baris yang cocok di sisi kanan, hasil-set akan berisi nol. LEFT JOIN juga dikenal sebagai LEFT OUTER JOIN
.
select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a = b.b(+);
Hasil:
a | b
--+-----
1 | null
2 | null
3 | 3
4 | 4
7 | null
8 | null
select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.* from a,b where a.a(+) = b.b;
Hasil:
a | b
-----+----
3 | 3
4 | 4
null | 5
null | 6
FULL (OUTER) GABUNG :
GABUNG LENGKAP menciptakan hasil-set dengan menggabungkan hasil kedua GABUNG KIRI dan GABUNGAN KANAN. Rangkaian hasil akan berisi semua baris dari kedua tabel. Baris di mana tidak ada yang cocok, set hasil akan berisi nilai NULL.
select * from a FULL OUTER JOIN b on a.a = b.b;
Hasil:
a | b
-----+-----
1 | null
2 | null
3 | 3
4 | 4
null | 6
null | 5
7 | null
8 | null
Gabungan dalam - Gabungan dalam menggunakan salah satu dari kueri yang setara memberi persimpangan dua tabel , yaitu dua baris yang sama-sama mereka miliki.
Gabung luar kiri - Gabung luar kiri akan memberikan semua baris dalam A, ditambah setiap baris umum dalam B.
Gabung terluar penuh - Gabung terluar penuh akan memberi Anda gabungan A dan B, yaitu Semua baris dalam A dan semua baris dalam B. Jika sesuatu dalam A tidak memiliki datum yang sesuai dalam B, maka bagian B adalah null, dan sebaliknya
Join is not an intersection unless the tables have the same columns
Anda. Anda dapat bergabung dengan kolom apa pun yang Anda inginkan dan jika nilainya cocok, mereka akan bergabung bersama.
1. Inner Join: Disebut juga Join. Ini mengembalikan baris yang ada di kedua tabel kiri, dan tabel kanan hanya jika ada kecocokan . Kalau tidak, ia mengembalikan nol catatan.
Contoh:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
INNER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
2. Full Outer Join: Disebut juga Full Join. Ini mengembalikan semua baris yang ada di kedua tabel kiri, dan tabel kanan.
Contoh:
SELECT
e1.emp_name,
e2.emp_salary
FROM emp1 e1
FULL OUTER JOIN emp2 e2
ON e1.emp_id = e2.emp_id
3. Left Outer join: Atau cukup disebut Left Join. Ini mengembalikan semua baris yang ada di tabel kiri dan mencocokkan baris dari tabel kanan (jika ada).
4. Right Outer Join: Disebut juga Right Join. Ini mengembalikan baris yang cocok dari tabel kiri (jika ada), dan semua baris hadir di tabel Kanan.
Keuntungan Bergabung
Pertimbangkan di bawah 2 tabel:
EMP
empid name dept_id salary
1 Rob 1 100
2 Mark 1 300
3 John 2 100
4 Mary 2 300
5 Bill 3 700
6 Jose 6 400
Departemen
deptid name
1 IT
2 Accounts
3 Security
4 HR
5 R&D
Sebagian besar ditulis hanya sebagai GABUNG dalam kueri sql. Hanya mengembalikan catatan yang cocok di antara tabel.
Select a.empid, a.name, b.name as dept_name
FROM emp a
JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
Seperti yang Anda lihat di atas, Jose
tidak dicetak dari EMP di output karena dept_id 6
tidak menemukan kecocokan di tabel Departemen. Demikian pula, HR
dan R&D
baris tidak dicetak dari Departemen tabel karena mereka tidak menemukan kecocokan di tabel Emp.
Jadi, INNER BERGABUNG atau hanya BERGABUNG, hanya mengembalikan baris yang cocok.
Ini mengembalikan semua catatan dari tabel LEFT dan hanya catatan yang cocok dari tabel KANAN.
Select a.empid, a.name, b.name as dept_name
FROM emp a
LEFT JOIN department b
ON a.dept_id = b.deptid
;
empid name dept_name
1 Rob IT
2 Mark IT
3 John Accounts
4 Mary Accounts
5 Bill Security
6 Jose
Jadi, jika Anda mengamati output di atas, semua catatan dari tabel LEFT (Emp) dicetak hanya dengan catatan yang cocok dari tabel KANAN.
HR
dan R&D
baris tidak dicetak dari tabel Department karena mereka tidak menemukan kecocokan di tabel Emp pada dept_id.
Jadi, LEFT JOIN mengembalikan SEMUA baris dari tabel Kiri dan hanya baris yang cocok dari tabel KANAN.
Juga dapat memeriksa DEMO di sini .
Silakan lihat jawaban oleh Martin Smith untuk ilustrasi dan penjelasan yang lebih baik dari gabungan yang berbeda, termasuk dan terutama perbedaan antara FULL OUTER JOIN
, RIGHT OUTER JOIN
dan LEFT OUTER JOIN
.
Kedua tabel ini membentuk dasar untuk representasi huruf-huruf JOIN
di bawah ini:
SELECT *
FROM citizen
CROSS JOIN postalcode
Hasilnya akan menjadi produk Cartesian dari semua kombinasi. Tidak JOIN
diperlukan kondisi:
INNER JOIN
sama dengan: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
Hasilnya akan berupa kombinasi yang memenuhi persyaratan yang disyaratkan JOIN
:
LEFT OUTER JOIN
sama dengan LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
Hasilnya akan menjadi segalanya dari citizen
bahkan jika tidak ada kecocokan di postalcode
. Sekali lagi JOIN
diperlukan suatu kondisi:
Semua contoh telah dijalankan pada Oracle 18c. Mereka tersedia di dbfiddle.uk yang juga merupakan tempat screenshot dari tabel.
CREATE TABLE citizen (id NUMBER,
name VARCHAR2(20),
postal NUMBER, -- <-- could do with a redesign to postalcode.id instead.
leader NUMBER);
CREATE TABLE postalcode (id NUMBER,
postal NUMBER,
city VARCHAR2(20),
area VARCHAR2(20));
INSERT INTO citizen (id, name, postal, leader)
SELECT 1, 'Smith', 2200, null FROM DUAL
UNION SELECT 2, 'Green', 31006, 1 FROM DUAL
UNION SELECT 3, 'Jensen', 623, 1 FROM DUAL;
INSERT INTO postalcode (id, postal, city, area)
SELECT 1, 2200, 'BigCity', 'Geancy' FROM DUAL
UNION SELECT 2, 31006, 'SmallTown', 'Snizkim' FROM DUAL
UNION SELECT 3, 31006, 'Settlement', 'Moon' FROM DUAL -- <-- Uuh-uhh.
UNION SELECT 4, 78567390, 'LookoutTowerX89', 'Space' FROM DUAL;
JOIN
danWHERE
CROSS JOIN
menghasilkan baris sebagai The General Idea / INNER JOIN
:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows
Menggunakan CROSS JOIN
untuk mendapatkan hasil LEFT OUTER JOIN
memerlukan trik seperti menambahkan NULL
berturut - turut. Itu dihilangkan.
INNER JOIN
menjadi produk kartesius. Ini sama dengan The General Idea / CROSS JOIN
:
SELECT *
FROM citizen c
JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
Di sinilah join dalam benar-benar dapat dilihat sebagai cross join dengan hasil yang tidak cocok dengan kondisi yang dihapus. Di sini tidak ada baris yang dihasilkan dihapus.
Menggunakan INNER JOIN
untuk mendapatkan hasil LEFT OUTER JOIN
juga membutuhkan trik. Itu dihilangkan.
LEFT JOIN
menghasilkan baris sebagai The General Idea / CROSS JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN
LEFT JOIN
menghasilkan baris sebagai The General Idea / INNER JOIN
:
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
WHERE p.postal IS NOT NULL -- < -- removed the row where there's no mathcing result from postalcode
Pencarian internet gambar pada "sql join cross inner outer" akan menampilkan banyak diagram Venn. Saya dulu punya salinan cetak satu di meja saya. Tetapi ada masalah dengan representasi.
Diagram Venn sangat baik untuk teori himpunan, di mana suatu elemen dapat berada dalam satu atau kedua set. Tetapi untuk database, elemen dalam satu "set" tampaknya, bagi saya, adalah baris dalam sebuah tabel, dan karena itu tidak juga hadir di tabel lain. Tidak ada yang namanya satu baris hadir dalam beberapa tabel. Baris unik untuk tabel.
Self joins adalah kasus sudut di mana setiap elemen sebenarnya sama di kedua set. Tapi itu masih tidak bebas dari masalah di bawah ini.
Set A
mewakili set di sebelah kiri ( citizen
tabel) dan set B
adalah set di sebelah kanan ( postalcode
tabel) dalam diskusi di bawah ini.
Setiap elemen di kedua set dicocokkan dengan setiap elemen di set lain, artinya kita membutuhkan A
jumlah setiap B
elemen dan B
jumlah setiap A
elemen untuk mewakili produk Cartesian ini dengan tepat. Teori himpunan tidak dibuat untuk beberapa elemen identik dalam suatu himpunan, jadi saya menemukan diagram Venn untuk benar mewakili itu tidak praktis / mustahil. Sepertinya tidak UNION
cocok sama sekali.
Baris berbeda. The UNION
adalah 7 baris total. Tapi mereka tidak kompatibel untuk SQL
set hasil yang umum . Dan ini bukan cara CROSS JOIN
kerjanya sama sekali:
Mencoba menampilkannya seperti ini:
..tapi sekarang itu hanya terlihat seperti INTERSECTION
, yang tentu saja tidak . Selain itu tidak ada elemen dalam INTERSECTION
yang sebenarnya ada di salah satu dari dua set yang berbeda. Namun, sangat mirip dengan hasil yang dapat dicari yang mirip dengan ini:
Untuk referensi, satu hasil yang dapat dicari untuk CROSS JOIN
s dapat dilihat di Tutorialgateway . The INTERSECTION
, seperti yang satu ini, kosong.
Nilai suatu elemen tergantung pada JOIN
kondisinya. Dimungkinkan untuk mewakili ini dengan syarat bahwa setiap baris menjadi unik untuk kondisi itu. Makna id=x
hanya berlaku untuk satu baris. Setelah baris dalam tabel A
( citizen
) cocok dengan beberapa baris dalam tabel B
( postalcode
) di bawah JOIN
kondisi, hasilnya memiliki masalah yang sama dengan CROSS JOIN
: Baris perlu diwakili beberapa kali, dan teori himpunan tidak benar-benar dibuat untuk itu. Di bawah kondisi keunikan, diagram dapat bekerja, tetapi perlu diingat bahwa JOIN
kondisi menentukan penempatan elemen dalam diagram. Melihat hanya pada nilai-nilai JOIN
kondisi dengan sisa baris hanya untuk perjalanan:
Representasi ini benar-benar terpisah ketika menggunakan INNER JOIN
dengan ON 1 = 1
kondisi yang membuatnya menjadi CROSS JOIN
.
Dengan self JOIN
, baris sebenarnya adalah elemen yang identik di kedua tabel, tetapi mewakili tabel sebagai keduanya A
dan B
tidak terlalu cocok. Sebagai contoh JOIN
kondisi diri umum yang membuat suatu elemen A
menjadi cocok dengan elemen yang berbeda di B adalah ON A.parent = B.child
, membuat kecocokan dari A
ke B
pada elemen yang terpisah. Dari contoh-contoh yang akan menjadi SQL
seperti ini:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
Meaning Smith adalah pemimpin Green dan Jensen.
Sekali lagi masalah dimulai ketika satu baris memiliki beberapa kecocokan untuk baris di tabel lainnya. Ini lebih rumit karena OUTER JOIN
dapat cocok dengan set kosong. Namun dalam teori himpunan penyatuan himpunan mana pun C
dan himpunan kosong, selalu adil C
. Set kosong tidak menambahkan apa pun. Representasi ini LEFT OUTER JOIN
biasanya hanya menunjukkan semua A
untuk mengilustrasikan bahwa baris A
yang dipilih terlepas dari apakah ada kecocokan atau tidak dari B
. Namun "elemen yang cocok" memiliki masalah yang sama dengan ilustrasi di atas. Mereka bergantung pada kondisinya. Dan set kosong tampaknya telah berkeliaran ke A
:
Menemukan semua baris dari a CROSS JOIN
dengan Smith dan kode pos di Bulan:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
AND p.area = 'Moon';
Sekarang diagram Venn tidak digunakan untuk mencerminkan JOIN
. Ini hanya digunakan untuk WHERE
klausa:
..dan itu masuk akal.
Seperti yang dijelaskan, INNER JOIN
sebenarnya bukan INTERSECT
. Namun INTERSECT
s dapat digunakan pada hasil permintaan yang terpisah. Di sini diagram Venn masuk akal, karena unsur-unsur dari kueri yang terpisah sebenarnya adalah baris yang dimiliki hanya oleh salah satu hasil atau keduanya. Persimpangan jelas hanya akan mengembalikan hasil di mana baris hadir di kedua kueri. Ini SQL
akan menghasilkan baris yang sama dengan yang di atas WHERE
, dan diagram Venn juga akan sama:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
INTERSECT
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
An OUTER JOIN
bukan a UNION
. Namun UNION
bekerja dalam kondisi yang sama seperti INTERSECT
, menghasilkan pengembalian semua hasil menggabungkan kedua SELECT
s:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
UNION
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE p.area = 'Moon';
yang setara dengan:
SELECT *
FROM citizen c
CROSS JOIN postalcode p
WHERE c.name = 'Smith'
OR p.area = 'Moon';
..dan memberikan hasilnya:
Juga di sini diagram Venn masuk akal:
Sebuah catatan penting adalah bahwa ini hanya bekerja ketika struktur hasil dari dua SELECT yang sama, memungkinkan perbandingan atau serikat. Hasil dari kedua ini tidak akan memungkinkan itu:
SELECT *
FROM citizen
WHERE name = 'Smith'
SELECT *
FROM postalcode
WHERE area = 'Moon';
..mencoba menggabungkan hasil dengan UNION
memberi a
ORA-01790: expression must have same datatype as corresponding expression
Untuk minat lebih lanjut bacalah Say NO to Venn Diagram When Explaining JOINs dan sql gabung sebagai venn diagram . Keduanya juga menutupi EXCEPT
.
Ada banyak jawaban bagus di sini dengan contoh aljabar relasional yang sangat akurat . Berikut ini adalah jawaban yang sangat sederhana yang mungkin berguna untuk para pembuat kode amatir atau pemula dengan dilema pengodean SQL.
Pada dasarnya, lebih sering daripada tidak, pertanyaan JOIN
bermuara pada dua kasus:
Untuk SELECT
subset data A
:
INNER JOIN
ketika data terkait yang B
Anda cari HARUS ada per desain basis data;LEFT JOIN
ketika data terkait yang B
Anda cari MUNGKIN atau MUNGKIN TIDAK ada per desain basis data.Perbedaan antara inner join
dan outer join
adalah sebagai berikut:
Inner join
adalah gabungan yang menggabungkan tabel berdasarkan tupel yang cocok, sedangkan outer join
gabungan adalah tabel gabungan berdasarkan pada tupel yang cocok dan tidak cocok.Inner join
menggabungkan baris yang cocok dari dua tabel di mana baris yang tidak cocok dihilangkan, sedangkan outer join
gabungan baris dari dua tabel dan baris yang tidak cocok mengisi dengan nilai nol.Inner join
seperti operasi persimpangan, sedangkan outer join
seperti operasi serikat.Inner join
adalah dua jenis, sedangkan outer join
tiga jenis.outer join
lebih cepat dari inner join
.