Apa perbedaan antara Joins Kiri, Kanan, Luar dan Dalam?

562

Saya bertanya-tanya bagaimana membedakan semua gabungan yang berbeda ini ...

Tuan
sumber
60
dari Coding Horror Penjelasan Visual SQL Bergabung
SQLMenace
3
Juga tergantung pada tingkat pemahaman, untuk seseorang seperti Anda bahwa artikel tidak apa-apa tapi bagi seseorang yang mungkin tidak sepenuhnya memahami bergabung itu cukup jelas
SQLMenace
6
Ini adalah duplikat dari stackoverflow.com/questions/419375/sql-join-dferences dan tidak diragukan lagi ...
cletus
1
Ini banyak membantu saya ... cara termudah adalah membuat tabel tes dan bermain dengannya. = P
daGrevis
1
kemungkinan rangkap dari Perbedaan antara gabungan dalam dan luar
tacaswell

Jawaban:

797

Contoh Sederhana : Katakanlah Anda punya Studentsmeja, dan Lockersmeja. Dalam SQL, tabel pertama yang Anda tentukan dalam gabungan Students,, adalah tabel LEFT , dan yang kedua Lockers,, adalah tabel KANAN .

Setiap siswa dapat ditugaskan ke loker, sehingga ada LockerNumberkolom di Studenttabel. Lebih dari satu siswa berpotensi berada dalam satu loker, tetapi terutama pada awal tahun ajaran, Anda mungkin memiliki beberapa siswa masuk tanpa loker dan beberapa loker yang tidak memiliki siswa yang ditugaskan.

Demi contoh ini, katakanlah Anda memiliki 100 siswa , 70 di antaranya memiliki loker. Anda memiliki total 50 loker , 40 di antaranya memiliki setidaknya 1 siswa dan 10 loker tidak memiliki siswa.

INNER JOIN setara dengan " tunjukkan semua siswa dengan loker ".
Siswa mana pun tanpa loker, atau loker tanpa siswa tidak ada.
Mengembalikan 70 baris

LEFT OUTER JOIN akan menjadi " tunjukkan semua siswa, dengan loker yang sesuai jika mereka punya ".
Ini mungkin daftar siswa umum, atau dapat digunakan untuk mengidentifikasi siswa tanpa loker.
Mengembalikan 100 baris

RIGHT OUTER JOIN akan menjadi " tunjukkan semua loker, dan siswa ditugaskan kepada mereka jika ada ".
Ini dapat digunakan untuk mengidentifikasi loker yang tidak memiliki siswa yang ditugaskan, atau loker yang memiliki terlalu banyak siswa.
Mengembalikan 80 baris (daftar 70 siswa di 40 loker, ditambah 10 loker tanpa siswa)

FULL OUTER JOIN akan konyol dan mungkin tidak banyak digunakan.
Sesuatu seperti " tunjukkan semua siswa dan semua loker, dan sesuaikan di mana Anda bisa "
Mengembalikan 110 baris (semua 100 siswa, termasuk yang tanpa loker. Ditambah 10 loker tanpa siswa)

CROSS JOIN juga cukup konyol dalam skenario ini.
Itu tidak menggunakan lockernumberbidang tertaut di tabel siswa, jadi Anda pada dasarnya berakhir dengan daftar raksasa besar dari setiap pasangan siswa-ke-loker, apakah itu benar-benar ada atau tidak.
Mengembalikan 5.000 baris (100 siswa x 50 loker). Bisa berguna (dengan penyaringan) sebagai titik awal untuk mencocokkan siswa baru dengan loker kosong.

BradC
sumber
12
Menggunakan contoh Anda, bergabung dengan CROSS akan berguna sebagai titik awal untuk membuat tugas loker: mulai dengan semua kombinasi yang mungkin dan kemudian gunakan kriteria lain untuk menyaring hasil dari daftar.
Joel Coehoorn
1
Jawaban bagus. Saya percaya Cross Join paling sering digunakan untuk menghasilkan data pengujian dari beberapa baris ketika Anda membutuhkan banyak catatan.
Eli
6
GABUNGAN LUAR PENUH dapat berguna saat mencari data yatim, atau saat membandingkan versi berbeda dari kumpulan data yang sama.
Lara Dougan
3
Cross gabung dengan produk cartesian
JavaRocky
3
Saya pikir bagaimana Anda memulai permintaan Anda berdampak pada hasil dari tipe join. Misalnya, SELECT * FROM students RIGHT OUTER JOIN lockers...akan menghasilkan hasil yang berbeda dari SELECT * FROM lockers RIGHT OUTER JOIN students.... Jawaban yang bagus, tetapi akan senang melihatnya diperbarui dengan SQLpertanyaan lengkap
jbmilgrom
141

Ada tiga tipe dasar bergabung:

  • INNERjoin membandingkan dua tabel dan hanya mengembalikan hasil jika ada kecocokan. Catatan dari tabel 1 digandakan ketika mereka cocok dengan banyak hasil di 2. INNER bergabung cenderung membuat set hasil lebih kecil, tetapi karena catatan dapat digandakan, ini tidak dijamin.
  • CROSSjoin membandingkan dua tabel dan mengembalikan setiap kemungkinan kombinasi baris dari kedua tabel. Anda bisa mendapatkan banyak hasil dari gabungan semacam ini yang bahkan mungkin tidak bermakna, jadi gunakan dengan hati-hati.
  • OUTERjoin membandingkan dua tabel dan mengembalikan data saat kecocokan tersedia atau nilai NULL sebaliknya. Seperti halnya dengan bergabung dengan INNER, ini akan menduplikasi baris dalam satu tabel ketika cocok dengan beberapa catatan di tabel lainnya. OUTER bergabung cenderung membuat set hasil lebih besar, karena mereka tidak akan dengan sendirinya menghapus catatan apa pun dari set tersebut. Anda juga harus memenuhi syarat bergabung dengan OUTER untuk menentukan kapan dan di mana menambahkan nilai NULL:
    • LEFT berarti menyimpan semua catatan dari tabel 1 tidak peduli apa dan menyisipkan nilai NULL ketika tabel 2 tidak cocok.
    • RIGHT berarti kebalikannya: simpan semua catatan dari tabel ke-2 tidak peduli apa dan sisipkan nilai NULL saat tabel pertama tidak cocok.
    • FULL berarti menyimpan semua catatan dari kedua tabel, dan menyisipkan nilai NULL di tabel mana pun jika tidak ada kecocokan.

Seringkali Anda melihat OUTERkata kunci dihilangkan dari sintaksis. Alih-alih itu hanya akan "BERGABUNG KIRI", "BERGABUNG KANAN", atau "GABUNG LENGKAP". Ini dilakukan karena INNER dan CROSS bergabung tidak memiliki arti sehubungan dengan KIRI, KANAN, atau PENUH, dan karenanya ini cukup dengan sendirinya untuk secara jelas menunjukkan bergabung dengan OUTER.

Berikut adalah contoh kapan Anda mungkin ingin menggunakan masing-masing jenis:

  • INNER: Anda ingin mengembalikan semua catatan dari tabel "Faktur", bersama dengan "Faktur" yang sesuai. Ini mengasumsikan bahwa setiap Faktur yang valid akan memiliki setidaknya satu baris.
  • OUTER: Anda ingin mengembalikan semua catatan "Faktur" untuk Faktur tertentu, beserta catatan "InventoryItem" yang sesuai. Ini adalah bisnis yang juga menjual layanan, sehingga tidak semua InvoiceLines akan memiliki IventoryItem.
  • CROSS: Anda memiliki tabel digit dengan 10 baris, masing-masing memegang nilai '0' hingga '9'. Anda ingin membuat tabel rentang tanggal untuk bergabung, sehingga Anda berakhir dengan satu catatan untuk setiap hari dalam rentang tersebut. Dengan bergabung dengan CROSS tabel ini dengan dirinya sendiri berulang kali, Anda dapat membuat bilangan bulat berurutan sebanyak yang Anda butuhkan (mengingat Anda mulai dari kekuatan 10 hingga 1, setiap bergabung menambahkan 1 ke eksponen). Kemudian gunakan fungsi DATEADD () untuk menambahkan nilai-nilai itu ke tanggal dasar Anda untuk rentang.
Joel Coehoorn
sumber
1
Bagus. Saya hanya akan menambahkan itu biasanya jika Anda hanya menulis 'GABUNG' artinya INNER GABUNG.
matpop
47

Hanya ada 4 macam:

  1. Bergabung dalam : Jenis yang paling umum. Baris output dihasilkan untuk setiap pasangan baris input yang cocok dengan kondisi gabungan.
  2. Gabung luar kiri : Sama seperti gabung dalam, kecuali bahwa jika ada baris yang tidak ditemukan baris yang cocok di tabel di sebelah kanan, sebuah baris adalah output yang berisi nilai-nilai dari tabel di sebelah kiri, dengan NULLuntuk setiap nilai dalam tabel di sebelah kanan. Ini berarti bahwa setiap baris dari tabel di sebelah kiri akan muncul setidaknya sekali dalam output.
  3. Gabung luar kanan : Sama seperti gabung luar kiri, kecuali dengan peran tabel terbalik.
  4. Full outer join : Kombinasi gabungan luar kiri dan kanan. Setiap baris dari kedua tabel akan muncul di output setidaknya satu kali.

"Gabung silang" atau "gabung kartesius" hanyalah gabung dalam yang tidak ada ketentuan gabung yang ditentukan, menghasilkan semua pasangan baris yang dihasilkan.

Terima kasih kepada RusselH karena telah menunjukkan FULL joins, yang saya hilangkan.

j_random_hacker
sumber
1
bagaimana dengan gabung penuh luar dan gabung silang (produk Cartesian)?
SQLMenace
penuh benar-benar setara dengan dua
gabungan
25
FULL adalah apa yang Anda dapatkan ketika Anda mengacaukan sambungan batin Anda, dan kemudian Anda mengajukan pertanyaan di sini "mengapa saya mendapatkan baris N ^ 2 bukannya N"? Lalu semua orang mendapat SALIB pada Anda.
Paul Tomblin
24

SQL GABUNG perbedaan:

Sangat mudah diingat:

INNER JOIN hanya menampilkan catatan yang umum untuk kedua tabel.

OUTER JOIN semua konten dari kedua tabel digabung menjadi satu, apakah keduanya cocok atau tidak.

LEFT JOINsama dengan LEFT OUTER JOIN- (Pilih catatan dari tabel pertama (paling kiri) dengan catatan tabel kanan yang cocok.)

RIGHT JOINsama dengan RIGHT OUTER JOIN- (Pilih catatan dari tabel kedua (paling kanan) dengan catatan tabel kiri yang cocok.)

masukkan deskripsi gambar di sini

Laxmi
sumber
Ada cara yang benar & relevan untuk memberi label lingkaran diagram Venn, tetapi ini bukan. Lingkaran bukan tabel input. Baris hasil juga bukan baris input, jadi deskripsi Anda salah di sana. Juga ini tidak jelas - Anda tidak menjelaskan "sama untuk keduanya", "cocok", "digabungkan".
philipxy
9

Lihat Gabung (SQL) di Wikipedia

  • Gabung dalam - Diberikan dua tabel gabung dalam mengembalikan semua baris yang ada di kedua tabel
  • gabungan kiri / kanan (luar) - Diberikan dua tabel mengembalikan semua baris yang ada di tabel kiri atau kanan bergabung Anda, ditambah baris dari sisi lain akan dikembalikan ketika klausa gabungan adalah pertandingan atau nol akan dikembalikan untuk kolom-kolom itu

  • Full Outer - Diberikan dua tabel mengembalikan semua baris, dan akan mengembalikan nol ketika kolom kiri atau kanan tidak ada

  • Cross Joins - Cartesian bergabung dan bisa berbahaya jika tidak digunakan dengan hati-hati

JoshBerke
sumber
6

Membuatnya lebih terlihat mungkin membantu. Satu contoh:

Tabel 1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

Meja 2:

ID_STUDENT LOCKER

3               l1
4               l2
5               l3

Apa yang saya dapatkan ketika saya lakukan:

-Inner join of Table 1 and Table 2: 

    - Inner join returns both tables merged only when the key 
      (ID_STUDENT) exists in both tables

    ID_STUDENT       STUDENT_NAME      LOCKER   

        3               Eduardo          l1
        4               Luiz             l2

-Left join of Table 1 and Table 2:

    - Left join merges both tables with all records form table 1, in 
      other words, there might be non-populated fields from table 2

    ID_ESTUDANTE    NOME_ESTUDANTE     LOCKER   

        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2

-Right join of table 1 and table 2:

    - Right join merges both tables with all records from table 2, in 
      other words, there might be non-populated fields from table 1

    ID_STUDENT        STUDENT_NAME     LOCKER   

        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

-Outter join of table 1 and table 2:

    - Returns all records from both tables, in other words, there
      might be non-populated fields either from table 1 or 2.

    ID_STUDENT        STUDENT_NAME     LOCKER   
        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3
lfvv
sumber
4

LEFT JOINdan RIGHT JOINjenis OUTER JOINs.

INNER JOIN adalah default - baris dari kedua tabel harus cocok dengan kondisi join.

RussellH
sumber
5
Saya tidak percaya bagaimana jawaban ini memiliki banyak upvotes dan pada saat yang sama tidak lengkap.
nbro
Saya pikir itu adalah jawaban yang lebih baik untuk pertanyaan awal.
RussellH
3

Gabungan dalam : Hanya tampilkan baris, kapan data dari kedua tabel.

Bergabung luar : (kiri / kanan) : Tampilkan semua hasil dari kiri / kanan meja dengan baris dipasangkan ( s ), jika ada atau tidak.

Pethő Jonatán
sumber
2

Pada awalnya Anda harus memahami apa yang dilakukan dengan bergabung? Kami menghubungkan beberapa tabel dan mendapatkan hasil spesifik dari tabel yang digabungkan. Cara paling sederhana untuk melakukan ini adalah cross join .

Katakanlah tableA memiliki dua kolom A dan B. Dan tableB memiliki tiga kolom C dan D. Jika kita menerapkan cross join maka akan menghasilkan banyak baris yang tidak berarti. Maka kita harus mencocokkan menggunakan kunci utama untuk mendapatkan data aktual.

Kiri: ini akan mengembalikan semua catatan dari tabel kiri dan catatan yang cocok dari tabel kanan.

Kanan: itu akan kembali berlawanan dengan Left join. Ini akan mengembalikan semua catatan dari tabel kanan dan catatan yang cocok dari tabel kiri.

Inner: Ini seperti persimpangan. Ini akan mengembalikan hanya catatan yang cocok dari kedua tabel.

Luar: Dan ini seperti persatuan. Ini akan mengembalikan semua catatan yang tersedia dari kedua tabel.

Terkadang kita tidak membutuhkan semua data, dan kita juga hanya membutuhkan data atau catatan umum. kita dapat dengan mudah mendapatkannya menggunakan metode bergabung ini. Ingat gabung kiri dan kanan juga gabung luar.

Anda bisa mendapatkan semua catatan hanya menggunakan gabung silang. Tapi itu bisa mahal jika menyangkut jutaan rekaman. Jadi sederhanakan dengan menggunakan gabungan kiri, kanan, dalam atau luar.

Terima kasih

HM Nayem
sumber