“INNER JOIN” ve “OUTER JOIN” arasındaki fark nedir?


4671

Ayrıca nasıl LEFT JOIN, RIGHT JOINve FULL JOINfit?


63
Aşağıdaki cevaplar ve yorumlar ve referanslarından sadece biri Venn diyagramlarının operatörleri nasıl temsil ettiğini açıklar: Daire kesişme alanı A JOIN B'deki satır kümesini temsil eder. A JOIN B'ye katılmayan ve diğer tabloya özgü sütunları NULL olarak ayarlayan tablonun satırları. (Ve çoğu A ve B'ye dairelerin belirsiz bir sahte yazışmasını verir.)
philipxy

1
Aşağıdaki teori temelli cevaplardan gerçek bir dünya uygulamasına atlamak: Genellikle deney verileriyle çalışıyorum, işlemci tasarımları üzerinde kıyaslamalar yapıyorum. Genellikle sonuçları 2 veya daha fazla donanım seçeneği arasında karşılaştırmak istiyorum. INNER JOIN, yalnızca tüm denemelerde başarılı bir şekilde yürütülen karşılaştırmaları gördüğüm anlamına gelir; OUTER JOIN, bazı yapılandırmalarda çalıştırılamayanlar da dahil olmak üzere tüm denemeleri görebildiğim anlamına gelir. Bu tür deneylerde başarısızlıkları ve başarıları görmek önemlidir. Birçok
RDBMS

4
Birçok cevap zaten sağlandı ama ben bu öğretici belirtilen görmedim. Venn diyagramlarını biliyorsanız, bu harika bir öğreticidir: blog.codinghorror.com/a-visual-explanation-of-sql-joins Benim için hızlı bir okuma olacak kadar özlüdür, ancak yine de tüm konsepti kavrar ve tüm çok iyi durumda. Venn diyagramlarının ne olduğunu bilmiyorsanız - bunları öğrenin. 5-10 dakika sürer ve setlerle çalışmayı ve setler üzerindeki işlemleri yönetirken görselleştirmeniz gerektiğinde yardımcı olacaktır.
DanteTheSmith

14
@DanteTheSmith Hayır, buradaki diyagramlarla aynı sorunlardan muzdarip. Yukarıdaki yorum ve aşağıdaki çok blog yazısı: "Jeff blogunda yorumlarda birkaç sayfa aşağı". Venn diyagramları kümelerdeki elemanları gösterir. Setlerin tam olarak ne olduğunu ve bu diyagramlardaki elemanların ne olduğunu tanımlamaya çalışın. Kümeler tablo değil , öğeler sıra değil . Ayrıca herhangi iki tablo birleştirilebilir, bu yüzden PK'lar ve FK'ler geçersizdir. Tamamen sahte. Binlerce kişinin yaptığı şeyi yapıyorsunuz - (yanlış) mantıklı olduğunu düşündüğünüz belirsiz bir izlenim var .
philipxy

3
Chris Bu makaleyi okumanızı tavsiye ederim: directiondatascience.com/… ... ve kabul edilen cevap seçiminizi (belki de ödüllü olana) Venn diyagramlarını kullanmayan bir cevap olarak değiştirmeyi düşünün. Şu anda kabul edilen cevap çok fazla insanı yanlış yönlendiriyor. Bunu topluluğumuzun iyiliği ve bilgi tabanımızın kalitesi için yapmanızı tavsiye ediyorum.
Colm Bhandal

Yanıtlar:


6114

Yinelenmeyen sütunlara katıldığınızı varsayarsak, bu çok yaygın bir durumdur:

  • A ve B'nin iç birleşimi A kesişimi B'nin sonucunu verir, yani bir Venn diyagramı kesişiminin iç kısmı .

  • A ve B'nin dış birleşimi A birleşimi B'nin sonuçlarını, yani bir Venn diyagram birleşiminin dış kısımlarını verir.

Örnekler

Her birinde tek bir sütun bulunan iki tablonuz olduğunu ve verilerin aşağıdaki gibi olduğunu varsayalım:

A    B
-    -
1    3
2    4
3    5
4    6

(1,2) 'nin A'ya, (3,4)' ün yaygın ve (5,6) 'nın B'ye özgü olduğuna dikkat edin.

İç birleşim

Eşdeğer sorgulardan birini kullanan bir iç birleşim iki tablonun, yani ortak iki satırın kesişimini verir.

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

Sol dış katılma

Sol dış birleşim A'daki tüm satırları ve B'deki ortak satırları verecektir.

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

Sağ dış birleşim

Sağ dış birleşim B'deki tüm satırları ve A'daki tüm ortak satırları verecektir.

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

Tam dış birleşim

Tam bir dış birleşim size A ve B birleşimini, yani A'daki tüm satırları ve B'deki tüm satırları verecektir. A'daki bir şeyin B'de karşılık gelen bir verisi yoksa, B kısmı boştur ve yardımcısı versa.

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

41
Tablo B'ye 4 değeriyle başka bir satır ekleyerek örneği artırmak iyi olur. Bu, iç birleşimlerin eşit satır sayısı üzerinde olması gerekmediğini gösterecektir.
softveda

472
Bununla birlikte mükemmel bir açıklama, ancak bu ifade: A ve B'nin dış birleşimi A birleşimi B'nin sonuçlarını, yani bir venn diyagram birleşiminin dış kısımlarını verir. doğru bir şekilde ifade edilmedi. Dış birleşim, aşağıdakilerden birine ek olarak A kesişen B'nin sonuçlarını verecektir: A'nın tümü (sol birleşim), tüm B (sağ birleşim) veya A'nın tamamı ve B'nin tamamı (tam birleşim). Sadece bu son senaryo gerçekten Birlik B'dir. Yine de, iyi yazılmış bir açıklama.
Thomas

11
TAM BİRLEŞTİRMENİN TAM DIŞ BİRLEŞTİRME'nin bir takma adı ve SOL BİRLEŞTİRMENİN SOL DIŞ BİRLEŞTİRME'nin bir takma adı olduğu doğru mu?
Damian

3
evet harika ve mükemmel bir açıklama. ama neden b sütununda değerler düzgün değil? yani 6,5 5,6 değil mi?
Ameer

7
@Ameer, Teşekkürler. Join bir sipariş garantisi vermez, ORDER BY deyimi eklemeniz gerekir.
Mark Harrison

733

Venn diyagramları bunu benim için gerçekten yapmıyor.

Örneğin, çapraz birleştirme ve bir iç birleşme arasında herhangi bir ayrım göstermezler veya daha genel olarak farklı birleştirme yüklemi türleri arasında herhangi bir ayrım göstermezler veya nasıl çalışacakları hakkında bir çerçeve sunarlar.

Mantıksal işlemeyi anlamak için bir ikame yoktur ve yine de kavramak nispeten kolaydır.

  1. Çapraz birleşimi düşünün.
  2. Yüklemin değerlendirdiği onsatırları koruyarak, 1. adımdaki tüm satırlara göre cümleyi değerlendirintrue
  3. (Yalnızca dış birleşimler için) 2. adımda kaybolan tüm dış satırlara ekleyin.

(Not: Pratikte, sorgu optimize edici, sorguyu yürütmek için yukarıdaki tamamen mantıklı açıklamadan daha etkili yollar bulabilir, ancak nihai sonuç aynı olmalıdır)

Tam bir dış birleştirmenin animasyonlu bir sürümü ile başlayacağım . Daha fazla açıklama aşağıdadır.

resim açıklamasını buraya girin


açıklama

Kaynak Tabloları

bağlantı açıklamasını buraya girin

İlk olarak bir CROSS JOIN(AKA Kartezyen Ürünü) ile başlayın . Bu bir ONcümle yok ve sadece iki tablodaki her satır kombinasyonunu döndürür.

A.Renk, B.RENÇ BİR ÇAPRAZ BAĞLANTI SEÇİN B

bağlantı açıklamasını buraya girin

İç ve Dış birleşimler "AÇIK" yantümceye sahiptir.

  • İç birleşim. Çapraz birleştirme sonucundaki tüm satırlar için "ON" yan tümcesindeki koşulu değerlendirin. True ise, birleştirilen satırı döndürür. Aksi takdirde atın.
  • Sol dış katılma. İç birleşim ile aynı şekilde, sol tablodaki hiçbir şeyle eşleşmeyen satırlar için, bunları sağ tablo sütunları için NULL değerlerle çıkarır.
  • Sağ Dış Birleştirme. İç birleşim ile aynı şekilde, sağ tablodaki hiçbir şeyle eşleşmeyen satırlar için bunları sol tablo sütunları için NULL değerlerle çıkarır.
  • Tam Dış Birleştirme. İç birleşim ile aynı, sol dış birleşimdeki gibi sol eşleşmemiş satırları ve sağ dış birleşimdeki gibi sağ eşleşmeyen satırları koruyun.

Bazı örnekler

A.Colour, B.Color INNER JOIN B'den A.Colour = B.Colour ÜZERİNDEN SEÇİN

Yukarıdaki klasik equi birleştirme.

İç birleşim

Animasyonlu Sürüm

resim açıklamasını buraya girin

A.Colour, B.Color INNER JOIN B'DEN A.Colour IN IN'DE DEĞİL ('Yeşil', 'Mavi')

İç birleşim koşulunun mutlaka bir eşitlik koşulu olması gerekmez ve tabloların her ikisinden (hatta ikisinden) sütunlara başvurması gerekmez. A.Colour NOT IN ('Green','Blue')Çapraz birleştirmenin her satırında değerlendirme .

iç 2

A.Colour, B.Color INNER JOIN B'DEN SEÇİN 1 = 1

Birleştirme koşulu, çapraz birleştirme sonucundaki tüm satırlar için doğru olarak değerlendirilir, böylece bu bir çapraz birleştirme ile aynıdır. 16 satırın resmini tekrarlamayacağım.

A.Colour, B.Colour'UN SOL DIŞ BİR DIŞTAN BAĞLANMASI B A.Colour = B.Colour

Dış birleşimler mantıksal olarak iç birleşimlerle aynı şekilde değerlendirilir, ancak sol tablodaki bir satır (sol birleşim için) sağ el tablosundaki herhangi bir satırla birleşmezse, sonuçta NULLdeğerlerle korunur. sağ sütunlar.

LOJ

A.Colour, B.Colour'UN SOL DIŞ BİR DIŞTAN BİRİNCİ A.Colour = B.Colour B.Colour NULL NEREDE

Bu, önceki sonucu yalnızca satırları döndürmekle kısıtlar B.Colour IS NULL. Bu özel durumda, bunlar sağdaki tabloda eşleşmedikleri için korunan satırlar olacaktır ve sorgu tabloda eşleşmeyen tek kırmızı satırı döndürür B. Bu anti-yarı birleşme olarak bilinir.

IS NULLTest için nullable olmayan veya birleştirme koşulunun NULLbu kalıbın düzgün çalışması ve herhangi bir NULLdeğere sahip satırları geri getirmekten kaçınmak için herhangi bir değerin hariç tutulmasını sağlaması için bir sütun seçmek önemlidir. sütununda eşleşmemiş satırlara ek olarak.

loj boş

A.Colour, B.Colour'U DOĞRU BİR DIŞTAN BAĞLAYIN A. A.Renk = B.Renk

Sağ dış birleşimler, sol dış birleşimlere benzer şekilde hareket ederler, ancak sağdaki tablodan eşleşmeyen satırları korurlar ve sol sütunları null uzatırlar.

ROJ

A.Colour, B.Colour'UN TAM DIŞ BİRİNDEN BAĞLANMASI B A.Renk = B.Renk

Tam dış birleşimler, sol ve sağ birleşimlerin davranışını birleştirir ve hem sol hem de sağ tablolardan eşleşmeyen satırları korur.

FOJ

A.Colour, B.CoULL TAM BİR DIŞTAN BAĞLANIN B AÇIK 1 = 0

Çapraz birleştirmedeki hiçbir satır 1=0yüklemle eşleşmez . Her iki taraftaki tüm satırlar, diğer taraftaki tablodaki sütunlarda NULL ile normal dış birleştirme kuralları kullanılarak korunur.

FOJ 2

TAM BİR DIŞ B BİRLEŞTİRMEDEN B renk 1 OLARAK KOALESCE (A.Colour, B.Colour) SEÇİN 1 = 0

Önceki sorguda yapılan küçük bir değişiklikle UNION ALL, iki tablodan birinin simülasyonu yapılabilir .

BİRLİK TÜMÜ

A.Colour, B.Colour'UN SOL DIŞ BİR DIŞTAN BAĞLANMASI A. A.Colour = B.Colour NEREDE B.Color = 'Green'

Not o WHEREfıkra (varsa) mantıksal olarak katıldıktan sonra çalışır. Yaygın olarak görülen bir hata, sol dış birleştirme gerçekleştirmek ve daha sonra sağ tabloda eşleşen olmayan satırlar dışında kalan bir koşula sahip bir WHERE yan tümcesini eklemektir. Yukarıdaki dış birleşmeyi gerçekleştirir ...

LOJ

... Ve sonra "Nerede" cümlesi çalışır. NULL= 'Green'dış birleşim tarafından korunan sıra atılır (mavi ile birlikte) birleştirmeyi etkili bir şekilde iç iç kısma dönüştürür.

LOJtoInner

Niyet, yalnızca B'nin Renk'in Yeşil olduğu satırları ve A'dan gelen tüm satırları doğru sözdizimine bakmaksızın

A.Colour, B.Colour'Ü SOL BİR DIŞTAN BAĞLAYIN A.Colour = B.Renk VE B.Renk = 'Green'

resim açıklamasını buraya girin

SQL Keman

SQLFiddle.com'da canlı olarak yayınlanan bu örneklere bakın .


46
Bunun benim için neredeyse Venn diyagramlarının yanı sıra işe yaramadığını söyleyeceğim, insanların farklı olduğunu ve farklı öğrendiğini takdir ediyorum ve bu daha önce gördüğüm gibi çok iyi bir açıklama, bu yüzden @ypercube'u destekliyorum bonus puanları vermek. Ayrıca JOIN yan tümcesinde WHERE yan tümcesine ek koşullar koymanın farkını açıklayan iyi çalışmalar. Sana şükrediyorum, Martin Smith.
Old Pro

22
@OldPro Venn diyagramları gittikleri kadar sorun değil, sanırım ama çapraz birleşmeyi temsil etme veya equi birleşimi gibi bir tür birleşim yüklemini birbirinden ayırma konusunda sessizler. Birleşim değerlendirmesinin çapraz birleşim sonucunun her satırındaki zihinsel modeli, daha sonra bir dış birleşim ise eşsiz satırlara geri eklenir ve son olarak benim için daha iyi çalıştığı yeri değerlendirir.
Martin Smith

18
Venn diyagramları, Birlikleri, Kavşakları ve Farklılıkları temsil etmek için iyidir, ancak birleşimleri temsil etmez. Çok basit birleşimler için küçük bir eğitim değerine sahiptirler, yani birleştirme koşulunun benzersiz sütunlarda olduğu birleşimler.
ypercubeᵀᴹ

12
@Arth - Hayır, yanılıyorsun. SQL Fiddle sqlfiddle.com/#!3/9eecb7db59d16c80417c72d1/5155 Venn diyagramlarının gösteremediği bir şey.
Martin Smith

7
@MartinSmith Wow, katılıyorum, tamamen yanılıyorum! Bire-adamlarla çalışmaya çok alışkın .. düzeltme için teşekkürler.
Arth

188

Birleştirmeler , iki tablodaki verileri birleştirmek için kullanılır ve sonuç yeni, geçici bir tablo olur. Birleştirmeler, birleştirme gerçekleştirmek için kullanılacak koşulu belirten yüklem adı verilen bir şey temelinde gerçekleştirilir. Bir iç birleşim ile dış birleşim arasındaki fark, iç birleşimin yalnızca birleşim yüklemine göre eşleşen satırları döndürmesidir. Örneğin- Çalışan ve Konum tablosunu ele alalım:

resim açıklamasını buraya girin

İç Birleştirme: - İç birleştirme, birleştirmeyüklemine dayalı olarakiki tablonun ( Çalışan ve Konum )sütun değerlerini birleştirerek yeni bir sonuç tablosu oluşturur. Sorgu, birleştirme yüklemini karşılayan tüm satır çiftlerini bulmak içinher Çalışan satırını her Konum satırıyla karşılaştırır. Birleştirmetahmini, NULL olmayan değerlerin eşleştirilmesinden memnun olduğunda, eşleşen her Çalışan ve Konum çifti için sütun değerleribir sonuç satırında birleştirilir. Bir iç birleşim için SQL şöyle görünecektir:

select  * from employee inner join location on employee.empID = location.empID
OR
select  * from employee, location where employee.empID = location.empID

Şimdi, SQL'in çalıştırılmasının sonucu şöyledir: resim açıklamasını buraya girin

Dış Birleştirme: - Bir dış birleştirme, birleştirilen iki tablodaki her kaydın eşleşen bir kayda sahip olmasını gerektirmez. Birleştirilmiş tablo, eşleşen başka bir kayıt olmasa bile her kaydı tutar. Dış birleşimler, hangi tablanın satırlarının tutulduğuna (sol veya sağ) bağlı olarak sol dış birleşimlere ve sağ dış birleşimlere ayrılır.

Sol Dış Birleştirme: - Tablolar için sol dış birleştirme (veya yalnızca sol birleştirme) sonucu Çalışan ve Konum her zaman "sol" tablodaki ( Çalışan )tüm kayıtları içerir, birleştirme koşulu eşleşen bir kayıt bulamasa bile "sağ" tablo ( Konum ). Soldaki bir birleştirme için SQL yukarıdaki tabloları kullanarak şöyle görünecektir:

select  * from employee left outer join location on employee.empID = location.empID;
//Use of outer keyword is optional

Şimdi, bu SQL çalıştırmanın sonucu şöyle görünecektir: resim açıklamasını buraya girin

Sağ Dış Birleşim : - Sağ dış birleşim (veya sağ birleşim), ters çevrilen tabloların tedavisi hariç, sol dış birleşmeye yakından benzemektedir. "Sağ" tablodaki ( Konum )her satır, birleştirilmiş tabloda en az bir kez görünür. "Sol" tablosu (hiçbir eşleştirme satır halinde Çalışan ) var, BOŞ gelen sütunlarda görünür Çalışan eşleşme sahip olan kayıtlar için yer . SQL şöyle görünür:

select * from employee right outer join location  on employee.empID = location.empID;
//Use of outer keyword is optional

Yukarıdaki tabloları kullanarak, sağ dış birleşimin sonuç kümesinin nasıl görüneceğini gösterebiliriz:

resim açıklamasını buraya girin

Tam Dış Birleşimler: - Tam Dış Birleştirme veya Tam Birleştirme, bir birleştirmenin sonuçlarına eşleşmeyen satırlar ekleyerek, tam olmayan bir dış birleşim kullanarak eşleşmeyen bilgileri saklamaktır. Diğer tablonun eşleşen bir değere sahip olup olmadığına bakılmaksızın, her iki tablodaki tüm satırları içerir.

Görüntü Kaynağı

MySQL 8.0 Başvuru Kılavuzu - Sözdizimine Katıl

Oracle Join işlemleri


3
Şimdiye kadarki en iyi cevap, alternatif sözdizimi - aradığım şey bu, teşekkürler!
Joey

1
Venn diyagramları yanlış etiketlenmiştir. Soru ve diğer cevaplar hakkındaki yorumlarıma bakın. Ayrıca bu dilin çoğu zayıf. Örneğin: "Birleştirme tahmini, NULL olmayan değerlerin eşleştirilmesinden memnun olduğunda, eşleşen her Çalışan ve Konum çifti için sütun değerleri bir sonuç satırında birleştirilir." Hayır, "Birleştirme yüklemesi NULL olmayan değerlerin eşleştirilmesiyle karşılandığında" değil. Satırlardaki değerler, bir bütün olarak koşulun doğru veya yanlış olmasından farklı değildir. Bazı değerler gerçek bir koşul için NULL olabilir.
philipxy

Açıkça belirtilmemesine rağmen, buradaki diyagramlar Venn diyagramlarıdır. Venn diyagramları genel olarak bir birleşmenin doğru matematiksel karakterizasyonu değildir. Venn diyagramlarını kaldırmanızı öneririm.
Colm Bhandal

@ColmBhandal: Venn diyagramlarını kaldırdı
ajitksharma

Tablolar ve ERD'ler dahil olmak üzere metin için lütfen resimler / bağlantılar değil metin kullanın . Görüntüleri yalnızca metin olarak ifade edilemeyen veya metin büyütme için kullanın. Resimler aranamaz veya kesilip yapıştırılamaz. Bir resimle bir açıklama / anahtar ve açıklama ekleyin.
philipxy

133

İç birleşim

Yalnızca eşleşen satırları alın, yani A intersect B.

Resim açıklamasını buraya girin

SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Sol dış katılma

İlk tablodaki tüm kayıtları ve ikinci tablodaki birleştirilmiş anahtarlarla eşleşen kayıtları seçin.

Resim açıklamasını buraya girin

SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Tam Dış Bağlantı

İkinci tablodaki tüm kayıtları ve ilk tablodaki birleştirilmiş anahtarlarla eşleşen kayıtları seçin.

Resim açıklamasını buraya girin

SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
    ON S.Advisor_ID = A.Advisor_ID

Referanslar


14
Aracın adı nedir? Satır ve venn şemalarını gösterdiğinden ilginç buluyorum
Grijesh Chauhan

2
@GrijeshChauhan Evet Ama şarabı kullanarak çalıştırmayı deneyebilirsiniz .
Tushar Gupta - curioustushar

2
Ohh! evet ben .. şarap kullanarak SQLyog kullandım .. orada da PlayOnLinux
Grijesh Chauhan

1
Metniniz belirsiz ve yanlış. "Yalnızca eşleşen satırlar" A & B'nin çapraz birleşiminden alınan satırlardır ve geri alınan (Bir iç birleşim B) A kesişen B değil ((Sol birleşim B)) kesişir (A sağ birleşim B). "Seçili" satırlar A & B'den değil, A çapraz birleştirme B'den ve A & B'den satırların genişletilmiş değerlerinden.
philipxy

@ TusharGupta-curioustushar "SQL Örnekleri için Kullanılan Tablolar" ı eklemelisiniz
Manuel Jordan

112

Basit bir ifadeyle:

Bir iç birleşim yalnızca eşleşen satırları alır.

Bir dış birleştirme eşleşen satırları bir tablodan ve diğer tablodaki tüm satırları alırken ... sonuç, hangisini kullandığınıza bağlıdır:

  • Sol : Sağ tablodaki eşleşen satırlar ve sol tablodaki tüm satırlar

  • Sağ : Sol tablodaki eşleşen satırlar ve sağ tablodaki tüm satırlar veya

  • Tam : Tüm tablolardaki tüm satırlar. Bir eşleşme olup olmadığı önemli değil


1
@nomen Değil Bu cevap adresleri o ama INNER JOIN olduğu bir kesişim ve TAM DIŞ gelen BİRLİĞİ olduğunu JOIN ise sol ve sağ setleri / çevreler (sırasıyla) SOL VE SAĞ katılmak satırlarını içerir. Not: Bu cevap girdi ve çıktı arasındaki satırlar hakkında net değildir. "Sol / sağ tablodaki" ile "sol / sağdaki sol / sağ kısmı" ile karıştırır ve "eşleştirilmiş satır" ile "all" ifadelerini kullanır.
philipxy

104

İç birleşim satırları yalnızca birleşmenin diğer (sağ) tarafında eşleşen bir kayıt varsa gösterir.

Bir (sol) dış birleştirme, birleştirme işleminin diğer (sağ) tarafında eşleşen satır olmasa bile, sol taraftaki her kayıt için satırları gösterir. Eşleşen satır yoksa, diğer (sağ) tarafın sütunları NULL değerini gösterir.


82

İç birleşimler, birleştirilen tabloda ilişkili bir kimliğe sahip bir kaydın bulunmasını gerektirir.

Dış birleşimler, sağ tarafta hiçbir şey olmasa bile sol taraf için kayıtlar döndürür.

Örneğin, bir Siparişler ve bir OrderDetails tablonuz var. Bunlar bir "OrderID" ile ilişkilidir.

Emirler

  • Sipariş Kimliği
  • Müşteri adı

Sipariş detayları

  • OrderDetailID
  • Sipariş Kimliği
  • Ürün adı
  • Adet
  • Fiyat

Talep

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
 INNER JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

yalnızca OrderDetails tablosunda da bir şey içeren Siparişler döndürür.

Eğer DIŞ SOL GİRİŞ olarak değiştirirseniz

SELECT Orders.OrderID, Orders.CustomerName
  FROM Orders 
  LEFT JOIN OrderDetails
    ON Orders.OrderID = OrderDetails.OrderID

hiçbir OrderDetails kaydı olmasa bile Siparişler tablosundan kayıtları döndürür.

Böyle bir konum cümlesi ekleyerek olası bir artık siparişi belirten OrderDetails içermeyen Siparişleri bulmak için bunu kullanabilirsiniz WHERE OrderDetails.OrderID IS NULL.


1
Basit ama gerçekçi örneği takdir ediyorum. Ben böyle bir istek değişti 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üzere 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 ASCbaşarı ile (MySQL). Ek koşullardan emin değildim, iyi
karıştılar

68

Basit bir ifadeyle:

İç birleşim -> SADECE üst ve alt tablolardan ortak kayıtlar alma Üst tablodaki birincil anahtarın Çocuk tablosundaki Yabancı anahtarla eşleştiği yer.

Sola katıl ->

sahte kod

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.
    }
  }

Sağ birleşim : Sol birleşimin tam tersi. Tablo adını LEFT JOIN'e sağ taraftaki sağ birleşime koyun, LEFT JOIN ile aynı çıktıyı elde edersiniz.

Dış birleşim : Her iki tabloda da tüm kayıtları göster No matter what. Sol tablodaki kayıtlar Birincil, Forieign anahtarına dayalı olarak sağ tabloyla eşleşmiyorsa, birleştirme sonucu NULL değerini kullanın.

Misal :

Misal

Şimdi 2 tablo için varsayalım

1.employees , 2.phone_numbers_employees

employees : id , name 

phone_numbers_employees : id , phone_num , emp_id   

Burada çalışanlar tablosu Master tablosu, phone_numbers_employees çocuk masasıdır (çocuk tablosunu emp_idbirbirine bağlayan yabancı anahtar olarak içerir employee.id.)

İç birleşimler

YALNIZCA 2 tablonun kayıtlarını alın .

Yani sorgu:

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;

Burada yalnızca birincil anahtar = yabancı anahtarda eşleşen satırları yukarıda açıklandığı gibi alın. Birincil anahtar = yabancı anahtarda eşleşmeyen satırlar birleştirme sonucunda atlanır.

Sol birleşimler :

Sol birleşim, sağ tabloda eşleşen bir satır olup olmadığına bakılmaksızın, sol tablonun tüm satırlarını korur.

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;

Dış birleşimler :

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;

Diyagrama benziyor:

Diyagram


4
Sonuç, birincil / benzersiz / aday anahtarlar ve yabancı anahtarlarla (kendi başına yapmak) hiçbir şey yapmaz. Baviour bunlara atıfta bulunulmaksızın tarif edilebilir ve tanımlanmalıdır. Çapraz birleştirme hesaplanır, daha sonra ON koşulu ile eşleşmeyen satırlar filtrelenir; ayrıca dış birleştirmeler için filtrelenmiş / eşleşmemiş satırlar
NULL'larla

SQL birleşimlerinin her zaman birincil / yabancı anahtarlarla eşleştiği varsayımı, Venn diyagramlarının bu yanlış kullanımına yol açar. Lütfen cevabınızı buna göre gözden geçirin.
Colm Bhandal

58

INNER JOINEşleşme olan her iki tablodaki tüm satırları döndürmek için kullanılır . Yani sonuçta ortaya çıkan tabloda tüm satır ve sütunların değerleri olacaktır.

Gelen OUTER JOINçıkan tabloda boş sütunlar olabilir. Dış birleşim LEFTveya olabilir RIGHT.

LEFT OUTER JOIN ikinci tabloda eşleşme olmasa bile, ilk tablodaki tüm satırları döndürür.

RIGHT OUTER JOIN ilk tabloda eşleşme olmasa bile ikinci tablodaki tüm satırları döndürür.



54

INNER JOINiki tablonun karşılaştırılmasında en az bir eşleşme olmasını gerektirir. Örneğin, A ٨ B (A kesişimi B) anlamına gelen tablo A ve tablo B.

LEFT OUTER JOIN ve LEFT JOIN aynı. Her iki tabloda eşleşen tüm kayıtları ve sol tablonun tüm olasılıklarını verir.

Benzer şekilde RIGHT OUTER JOINve RIGHT JOINaynı. Her iki tabloda eşleşen tüm kayıtları ve doğru tablonun tüm olasılıklarını verir.

FULL JOINçoğaltma LEFT OUTER JOINve RIGHT OUTER JOINçoğaltma olmadan birleşimidir .


43

Cevap her birinin anlamında, sonuçlarda.

Not:
içinde veya SQLiteyoktur . Ve ayrıca orada yok .RIGHT OUTER JOINFULL OUTER JOIN
MySQLFULL OUTER JOIN

Cevabım yukarıdaki nota dayanmaktadır .

Bunun gibi iki tablonuz olduğunda:

--[table1]               --[table2]
id | name                id | name
---+-------              ---+-------
1  | a1                  1  | a2
2  | b1                  3  | b2

CROSS JOIN / OUTER JOIN:
Bu tablo verilerinin tümünü şu şekilde CROSS JOINveya bununla elde edebilirsiniz ,:

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: Kullanabileceğiniz
bir ilişkiye dayalı olarak yukarıdaki sonuçlara filtre eklemek istediğinizde :table1.id = table2.idINNER 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] JOIN:
Yukarıdaki sonuçta tablolardan birinin tüm satırlarına sahip olmak istediğinizde - aynı ilişkiyle - şunları kullanabilirsiniz LEFT JOIN:
( RIGHT JOIN için sadece tabloların yerini değiştirin)

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:
Sonuçlarınızda diğer tablonun tüm satırlarına sahip olmak istediğinizde şunları kullanabilirsiniz 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

Eh, ihtiyaç olarak ihtiyacınızı kapsayan her birini seçin;).


Notunuza, MySQL'de de yok olduğunu ekleyebilirsiniz full outer join.
potashin

35

İç birleşim.

Birleştirme, iki tablodaki satırları birleştirir. Bir iç birleşim , sorguda belirttiğiniz ölçütlere göre iki tabloyu eşleştirmeye çalışır ve yalnızca eşleşen satırları döndürür. Birleştirmedeki ilk tablodan bir satır ikinci tablodaki iki satırla eşleşirse, sonuçlarda iki satır döndürülür. İlk tabloda ikinci satırdaki bir satırla eşleşmeyen bir satır varsa, döndürülmez; aynı şekilde, ikinci tabloda birincideki bir satırla eşleşmeyen bir satır varsa, döndürülmez.

Dış birleşim.

Bir katılmak sol ikinci tablodaki satırların ilk tablodan satırları maç bulmak için girişimlerini. Bir eşleşme bulamazsa, ilk tablodaki sütunları döndürür ve ikinci tablodaki sütunları boş bırakır (boş).


28

resim açıklamasını buraya girin

  • INNER JOINiki veya daha fazla tablo için en tipik birleştirme. Hem tablo AÇIK birincil anahtarında hem de forignkey ilişkisinde veri eşleşmesini döndürür.
  • OUTER JOINile aynıdır INNER JOIN, ancak NULLResultSet'teki verileri de içerir .
    • LEFT JOIN= INNER JOIN+ Sol tabloda Null, sağ tablodaki eşleşmeyle eşleşmeyen veriler .
    • RIGHT JOIN= INNER JOIN+ Sol tablodaki eşleşmeyle sağ tablonun Nulleşleşmeyen verileri .
    • FULL JOIN= INNER JOIN+ Hem sağ hem de sol tablolarda Nulleşleşmelerle eşleşmeyen veriler .
  • Bir tablo kendi başına verileri referans alan bir tablo kendi kendine birleştirme olarak bildiğinde, kendi kendine katılma SQL'de bir anahtar sözcük değildir. Kullanılması INNER JOINve OUTER JOINbiz öz sorguları katılmak yazabilir.

Örneğin:

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 

27

Diğer yanıtlarda performans ve optimize edici hakkında fazla ayrıntı görmüyorum.

Bazen sadece şunu bilmek iyidir INNER JOIN ilişkisel da optimize edicinin onunla oynamak için en fazla seçeneğe sahip olduğu anlamına gelir. Aynı sonucu daha hızlı tutmak için birleştirme sırasını yeniden düzenleyebilir. Optimize edici en birleştirme modlarını kullanabilir.

Genellikle INNER JOINfarklı tür birleşimler yerine kullanmaya çalışmak iyi bir uygulamadır . (Tabii ki beklenen sonuç kümesi göz önüne alındığında mümkünse.)

Bu garip ilişkisel davranış hakkında burada birkaç iyi örnek ve açıklama var:


4
Bir tür birleştirmeyi diğerine kullanmak muhtemelen "iyi uygulama" olamaz. Kullandığınız birleştirmeyi istediğiniz verileri belirler. Farklı bir tane kullanırsanız yanılıyorsunuz. Artı, Oracle'da en azından bu cevap tamamen yanlış. Her şey için tamamen yanlış geliyor ve kanıtınız yok. Kanıtın var mı?
Ben

1. Yani kullanmaya çalışın . LEFT OUTER birleşimlerini kullanan birçok insanın herhangi bir sebep olmadan her yerde gördüm. (Birleştirilen sütunlar 'boş' değildi.) Bu durumlarda INNER birleşimlerini kullanmak kesinlikle daha iyi olurdu. 2. İlişkisel olmayan davranışı yapabileceğimden daha iyi açıklayan bir bağlantı ekledim.
Lajos Veres

Bildiğim gibi çoğu zaman INNER JOINolduğundan daha yavaş LEFT JOIN, Ve insanlar LEFT JOINyerine beklenmedik sonuçları kaldırmak için INNER JOINbir ekleyerek kullanabilirsiniz ;). WHERENULL
shA.t

Bu yorumlar beni biraz belirsizleştirdi. Sizce neden INNERdaha yavaş?
Lajos Veres

Motora bağlıdır. gnu katılmak, joinkeys, DB2, MySQL. Gevşek yazım ya da açık bir oyuncu kadrosu gibi performans tuzakları boldur.
mckenzm

26

Çok sevilen kırmızı gölgeli Venn diyagramını eleştirdikten sonra, kendi girişimimi göndermenin sadece adil olduğunu düşündüm.

@Martin Smith'in cevabı uzun zamandır bu grubun en iyisi olsa da, her tablonun sadece anahtar sütununu gösterirken, ideal olarak anahtar olmayan sütunların da gösterilmesi gerektiğini düşünüyorum.

İzin verilen yarım saat içinde yapabileceğim en iyi şey, hala null değerlerinin anahtar değerlerin yokluğu nedeniyle orada TableBolduğunu veya OUTER JOINaslında bir birleşimden ziyade bir birlik olduğunu gösterdiğini düşünmüyorum :

resim açıklamasını buraya girin


2
Soru INNER ve OUTER birleşimleri arasındaki farkı istiyor, ancak mutlaka dış birleştirme lol
bırakmadı

@LearnByReading: Sağdaki fotoğrafım bir sağ dış ie katılmak yerine TableA a LEFT OUTER JOIN TableB bbirlikteTableB B RIGHT OUTER JOIN TableA a
onedaywhen

26

Hassas algoritması INNER JOIN, LEFT/RIGHT OUTER JOINaşağıdaki gibidir:

  1. Her satırı ilk tablodan alın: a
  2. Yanındaki ikinci tablodaki tüm satırları düşünün: (a, b[i])
  3. ON ...Her bir çift için maddeyi değerlendirin :ON( a, b[i] ) = true/false?
    • Koşul değerlendirildiğinde true, birleştirilmiş satırı döndürün (a, b[i]).
    • Herhangi bir eşleşme olmadan ikinci tablonun sonuna erişildiğinde ve bu, diğer tablonun tüm sütunları için Outer Joinbir (sanal) çift döndürür Null: (a, Null)SOL dış birleşim veya (Null, b)SAĞ dış birleşim için. Bu, ilk tablonun tüm satırlarının nihai sonuçlarda var olmasını sağlamak içindir.

Not:ON maddede belirtilen koşul herhangi bir şey olabilir, Birincil Anahtarlar kullanılması gerekmez (ve her iki tablodaki Sütunlara her zaman başvurmanız gerekmez)! Örneğin:

İç birleşim ve sol dış birleşim


resim açıklamasını buraya girin

Not: Sol Birleştirme = Sol Dış Birleştirme, Sağ Birleştirme = Sağ Dış Birleştirme.


20

En Basit Tanımlar

İç Birleştirme: Her iki tablodan da eşleşen kayıtları döndürür .

Tam Dış Birleştirme: Her İki Tablodan da eşleşen ve eşleşmeyen kayıtları Her İki Tablodaki eşleşmeyen kayıtlar için null değerine döndürür .

Sol Dış Birleştirme: Yalnızca sol taraftaki tablodan eşleşen ve eşleşmeyen kayıtları döndürür .

Sağ Dış Birleştirme: Yalnızca Sağ Taraftaki tablodan eşleşen ve eşleşmeyen kayıtları döndürür .

Kısacası

Eşleşen + Sol Eşleşmeyen + Sağ Eşleşmeyen = Tam Dış Birleştirme

Eşleşti + Sol Eşleşmedi = Sol Dış Birleştirme

Eşleşti + Sağ Eşleşmedi = Sağ Dış Birleştirme

Eşleşti = İç Bağlantı


1
Bu harika ve katılımın neden Zaman Serisi dizinleri için beklendiği gibi çalışmadığını açıklıyor. Bir saniye arayla zaman damgaları eşleşmez.
yeliabsalohcin

1
@yeliabsalohcin Soruya yaptığınız yorumda "beklendiği gibi" burada açıklamaz veya "çalışır". Sadece garip bir şekilde başkalarının sahip olmasını beklediğiniz açıklanamayan kişisel bir yanlış anlama. Okurken sözcükleri terbiyesizce ele alırsanız - net yazıyı yanlış yorumlamak ve / veya belirsiz yazımı kabul etmek - burada yazarken olduğu gibi yanlış anlamaların olmasını bekleyebilirsiniz. Aslında, buradaki çoğu gibi bu cevap belirsiz ve yanlıştır. "İç Birleştirme: Giriş sütunu kümeleri farklı olduğunda, her iki tabloda da eşleşen kayıtları döndürür" yanlıştır. Onun çalışırken belirli bir şey söylemek, ama değil . (Cevabımı görün.)
philipxy

9

Basit bir ifadeyle,

1. INNER JOIN VEYA EQUI JOIN: Her iki tabloda da yalnızca koşulla eşleşen sonuç kümesini döndürür.

2. DIŞ BİRLEŞTİR: Koşul eşleşmesi olsa da olmasa da her iki tablodaki tüm değerlerin sonuç kümesini döndürür.

3. SOL BİRLEŞTİR: Sol tablodaki tüm değerlerin sonuç kümesini ve yalnızca sağ tablodaki koşulla eşleşen satırları döndürür.

4. RIGHT JOIN: Sağ tablodaki tüm değerlerin sonuç kümesini ve yalnızca sol tablodaki koşulla eşleşen satırları döndürür.

5. FULL JOIN: Tam Birleştirme ve Tam Dış Birleştirme aynıdır.


5

SQL'de başlıca 2 tür JOIN vardır: [INNER ve OUTER]


Örnekler

Her birinde tek bir sütun bulunan iki tablonuz olduğunu ve verilerin aşağıdaki gibi olduğunu varsayalım:

A    B
-    -
1    3
2    4
3    5
4    6
7
8

(1,2,7,8) 'in A'ya, (3,4)' ün yaygın ve (5,6) 'nın B'ye özgü olduğuna dikkat edin.



  • (İÇ) KATIL :

INNER JOIN anahtar sözcüğü, koşul sağlandığı sürece her iki tablodaki tüm satırları seçer. Bu anahtar kelime, koşulun yerine getirildiği tabloların tüm satırlarını birleştirerek sonuç kümesini oluşturur; diğer bir deyişle ortak alanın değeri aynı olacaktır.

İÇ BİRLEŞİM

select * from a INNER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b;

Sonuç:

a | b
--+--
3 | 3
4 | 4


  • SOL (DIŞ) KATIL :

Bu birleştirme, birleştirme işleminin sol tarafındaki tablonun tüm satırlarını ve birleştirme işleminin sağ tarafındaki tablo için eşleşen satırları döndürür. Sağ tarafta eşleşen satır bulunmayan satırlar, sonuç kümesi null içerecektir. LEFT JOIN olarak da bilinir LEFT OUTER JOIN.

SOL KATIL / SOL DIŞ KATIL

select * from a LEFT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a = b.b(+);

Sonuç:

a |  b
--+-----
1 | null
2 | null
3 |    3
4 |    4
7 | null
8 | null


  • SAĞ (DIŞ) BİRLEŞTİR : Sağ tablodan tüm kayıtları ve sol tablodan eşleşen kayıtları döndürür

DOĞRU KATIL / DOĞRU DIŞ KATIL

select * from a RIGHT OUTER JOIN b on a.a = b.b;
select a.*, b.*  from a,b where a.a(+) = b.b;

Sonuç:

a    |  b
-----+----
3    |  3
4    |  4
null |  5
null |  6


  • TAM (DIŞ) KATIL :

    FULL JOIN, hem LEFT JOIN hem de RIGHT JOIN sonuçlarını birleştirerek sonuç kümesini oluşturur. Sonuç kümesi, her iki tablodaki tüm satırları içerir. Eşleşmesi olmayan satırlar, sonuç kümesi NULL değerler içerecektir.

TAM KATIL / TAM DIŞ KATIL

select * from a FULL OUTER JOIN b on a.a = b.b;

Sonuç:

 a   |  b
-----+-----
   1 | null
   2 | null
   3 |    3
   4 |    4
null |    6
null |    5
   7 | null
   8 | null

1
Venn diyagramları genel olarak SQL birleşimlerini tanımlamak için yeterli değildir. SQL birleşimlerinin tablolar arasındaki satırları bire bir eşleştirmesi gerekmez, örneğin yabancı anahtar veya birincil anahtar kullanılır.
Colm Bhandal

Satır eşleşmeden 2 tabloya nasıl katılırsınız? Birleştirme yapabilmek için birincil veya yabancı bir sütuna veya bazı ortak alanlara ihtiyacınız vardır. Bu cevabı neden indirdiğinizi merak ediyorum. Ve Venn diyagramı, SQL JOIN'in nasıl çalıştığını açıklayan kaynaktır. Birleşimleri temsil edecek daha iyi örnekleriniz var mı? Değilse, lütfen daha iyi çözümler elde etmek için oy verin. Teşekkür ederim.
Mayur

Diyagramları yazıya koyan sensin. Diyagramların efsanesi nedir? - Her setin öğeleri nelerdir? Peki ya masaların çantalar set olmadığı gerçeği? Sen söylemiyorsun. Set etmedikleri bir şey, etiket başına A & B satırlarıdır. Bu sayfadaki yayınlardaki yorumlarıma bakın. Bu yazı, başka yerlerde görülen ancak anlaşılmayan veya sorgulanmayan yanlış kullanımı körü körüne tekrar ediyor. Ayrıca burada metinde söyledikleriniz belirsiz ve yanlış. Ayrıca buradaki birçok cevaba hiçbir şey katmıyor. (Hemen hemen hepsi oldukça zayıf olmasına rağmen.) PS Lütfen yorumlarla değil, düzenlemelerle netleştirin.
philipxy

FK'lere katılmak veya sorgulamak için gerek yoktur. Herhangi bir 2 tablo, herhangi bir kısıtlama, tetikleyici veya iddiadan bağımsız olarak sütunlarını içeren herhangi bir koşulda birleştirilebilir.
philipxy

3
  • İç birleşim - Eşdeğer sorgulardan birini kullanan bir iç birleşim iki tablonun , yani ortak iki satırın kesişimini verir .

  • Sol dış birleştirme - Bir dış bıraktı katılmak B'de A'da tüm satırları, artı herhangi bir ortak satır verecek

  • Tam dış birleşim - Bir tam dış birleşim A'da şey B'de karşılık gelen veriyi yoksa size yani A'da tüm satırlar ve B'de tüm satırları A ve B birliği verecek, daha sonra B kısmıdır null ve versay


1
Bu hem yanlış hem de belirsiz. Birleştir, tablolar aynı sütunlara sahip olmadığı sürece bir kavşak değildir . Dış birleşimler, aynı sütunlara sahip olmadıkça A veya B'den satır içermez, bu durumda boş değer eklenmez. Bir şey söylemeye çalışıyorsunuz, ama söylemiyorsunuz. Doğru ya da net bir şekilde açıklamıyorsunuz.
philipxy

@ philipxy: İfadenize katılmıyorsunuz. Join is not an intersection unless the tables have the same columnsİstediğiniz sütunlara katılabilirsiniz ve değer eşleşirse bunlar birleştirilir.
SuicideSheep

Bu yorum cevabınız kadar net değil. (Sanırım böyle bir şey düşünüyor olabilirsiniz, sonucun ortak sütunları için alt satır değerleri kümesi, girdilerin her birinin ortak sütunları için alt satır değerleri kümelerinin kesişimidir; ancak yazdığınız şey bu değildir. açık değildir.)
philipxy

Demek istediğim, birleştirme sadece aynı sütunlara sahip girdilerin doğal bir iç birleşimi olduğunda girdilerin kesişmesidir. "Kavşak" ve "birleşim" kelimelerini yanlış kullanıyorsunuz.
philipxy

3

1. Inner Join: Join olarak da adlandırılır. Hem Sol tabloda hem de sağ tabloda bulunan satırları yalnızca bir eşleşme varsa döndürür . Aksi takdirde sıfır kayıt döndürür.

Misal:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
INNER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

çıkışı1

2. Tam Dış Birleştirme: Tam Birleştirme olarak da adlandırılır. Hem Sol tabloda hem de sağ tabloda bulunan tüm satırları döndürür .

Misal:

SELECT
  e1.emp_name,
  e2.emp_salary    
FROM emp1 e1
FULL OUTER JOIN emp2 e2
  ON e1.emp_id = e2.emp_id

çıkışı2

3. Sol Dış birleşim: Veya sadece Sol birleşim olarak adlandırılır. Sol tabloda bulunan tüm satırları ve sağ tablodan eşleşen satırları (varsa) döndürür.

4. Sağ Dış Birleştirme: Sağ Birleşme olarak da adlandırılır. Sol tablodan (varsa) eşleşen satırları ve Sağ tabloda bulunan tüm satırları döndürür.

katılır

Birleşimlerin Avantajları

  1. Daha hızlı çalışır.

2
Bu yalnızca tablolar aynı sütun kümesine sahip olduğunda doğrudur. (Kavşakla iç birleşimi ve sendika ile tam birleşmeyi karıştırır.) Ayrıca "maç" tanımsızdır. Diğer yorumlarımı oku.
philipxy

2

Aşağıdaki 2 tabloyu düşünün:

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

Bölüm

deptid  name
1       IT
2       Accounts
3       Security
4       HR
5       R&D

İç birleşim:

Çoğunlukla sql sorgularında JOIN olarak yazılır . Yalnızca tablolar arasındaki eşleşen kayıtları döndürür.

Tüm çalışanları ve departman adlarını öğrenin:

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

Yukarıda gördüğünüz gibi, Joseyazdırılan değildir EMP 's dept_id olarak çıktısında 6Bölümü tablosunda bir eşleşme bulmak. Benzer şekilde HRve Emp tablosunda bir eşleşme bulamadıklarından R&Dsatırlar Departman tablosundan yazdırılmaz .

INNER JOIN veya sadece JOIN, yalnızca eşleşen satırları döndürür.

SOL YÖNDEN KATILIM :

Bu, SOL tablodaki tüm kayıtları ve yalnızca SAĞ tablodaki eşleşen kayıtları döndürür.

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    

Dolayısıyla, yukarıdaki çıktıyı gözlemlerseniz, SOL tablodaki (Emp) tüm kayıtlar SAĞ tablodaki eşleşen kayıtlarla yazdırılır.

HRve dept_id üzerindeki Emp tablosunda bir eşleşme bulamadıklarından R&Dsatırlar Departman tablosundan yazdırılmaz .

Bu nedenle, LEFT JOIN TÜM satırları Sol tablodan ve yalnızca eşleşen satırları SAĞ tablodan döndürür.

Burada DEMO'yu da kontrol edebilirsiniz .


2

Genel Fikir

Bakınız cevabını tarafından Martin Smith , farklı dahil arasında özellikle farklılıklar katılır daha iyi illustations ve açıklamalar için FULL OUTER JOIN, RIGHT OUTER JOINve LEFT OUTER JOIN.

Bu iki tablo, JOINaşağıdaki örneklerin temsili için bir temel oluşturur :

temel

ÇAPRAZ KATIL

Crossjoin

SELECT *
  FROM citizen
 CROSS JOIN postalcode

Sonuç, tüm kombinasyonların Kartezyen ürünleri olacaktır. Hiçbir JOINkoşul gerekmez:

CrossJoinResult

İÇ BİRLEŞİM

INNER JOIN basitçe aynıdır: JOIN

İç birleşim

SELECT *
  FROM citizen    c
  JOIN postalcode p ON c.postal = p.postal

Sonuç, gerekli JOINkoşulu karşılayan kombinasyonlar olacaktır :

InnerJoinResult

SOL DIŞ KATILMA

LEFT OUTER JOIN aynıdır LEFT JOIN

Sol yönden katılım

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON c.postal = p.postal

Sonuç, citizenmaçlar olmasa bile her şey olacaktır postalcode. Yine bir JOINkoşul gereklidir:

LeftJoinResult

Oynatmak için veriler

Tüm örnekler bir Oracle 18c üzerinde çalıştırılmıştır. Tabloların ekran görüntülerinin de geldiği dbfiddle.uk adresinde mevcuttur .

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;

JOINVe ile oynarken bulanık sınırlarWHERE

ÇAPRAZ KATIL

CROSS JOINGenel Fikir olarak satırlarla sonuçlanan / INNER JOIN:

SELECT *
  FROM citizen          c
  CROSS JOIN postalcode p
 WHERE c.postal = p.postal -- < -- The WHERE condition is limiting the resulting rows

Bir CROSS JOINsonucu almak için kullanmak için arka arkaya LEFT OUTER JOINekleme gibi hileler gerekir NULL. Atlandı.

İÇ BİRLEŞİM

INNER JOINkartezyen bir ürün haline gelir. Genel Fikir / ile aynıdır CROSS JOIN:

SELECT *
  FROM citizen    c
  JOIN postalcode p ON 1 = 1  -- < -- The ON condition makes it a CROSS JOIN

İç birleşim gerçekten kaldırılan koşula uymayan sonuçlarla çapraz birleşim olarak görülebilir. Burada ortaya çıkan satırların hiçbiri kaldırılmaz.

INNER JOINSonuç almak için kullanmak LEFT OUTER JOINda hileler gerektirir. Atlandı.

SOL DIŞ KATILMA

LEFT JOINGenel Fikir olarak satırlarla sonuçlanır / CROSS JOIN:

SELECT *
  FROM citizen         c
  LEFT JOIN postalcode p ON 1 = 1 -- < -- The ON condition makes it a CROSS JOIN

LEFT JOINGenel Fikir olarak satırlarla sonuçlanır / 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

Venn diyagramı ile ilgili sorunlar

"Sql birleştirme çapraz iç dış" bir internet arama resim Venn diyagramları çok gösterecektir. Masamda bir tane basılı kopya vardı. Ancak temsil ile ilgili sorunlar var.

Venn diyagramı, bir elemanın bir veya iki sette olabileceği set teorisi için mükemmeldir. Ancak veritabanları için, bir "kümedeki" bir öğe, bana göre, bir tabloda bir satır gibi görünmektedir ve bu nedenle başka tablolarda da mevcut değildir. Birden çok tabloda mevcut bir satır diye bir şey yoktur. Bir satır tabloya özgüdür.

Kendi kendine birleşmeler, her öğenin aslında her iki sette de aynı olduğu bir köşe durumudur. Ancak, aşağıdaki sorunlardan hiçbiri hala ücretsiz değildir.

Küme A, soldaki seti ( citizentablo) ve küme B, postalcodeaşağıdaki tartışmada sağdaki seti ( tablo) temsil eder .

ÇAPRAZ KATIL

Her iki setlerinde her eleman biz gerek, yani diğer sette her eleman ile eşleştiği Aher miktarına Bunsurları ve Bher miktarına Adüzgün bu Kartezyen ürünü temsil etmek elemanları. Küme teorisi bir kümedeki birden fazla özdeş öğe için yapılmaz, bu yüzden onu pratik / imkansız olarak temsil etmek için Venn diyagramlarını buluyorum. Öyle görünmüyorUNION uygun .

Satırlar farklıdır. UNIONToplamda 7 sırasıdır. Ancak ortak bir SQLsonuç kümesi için uyumsuzdurlar . Ve bu hiç de böyle değil CROSS JOIN:

CrossJoinUnion1

Bunu şöyle temsil etmeye çalışıyorum:

CrossJoinUnion2Crossing

..ama şimdi sadece gibi görünüyor INTERSECTION, ki bu kesinlikle değil . Dahası INTERSECTION, aslında iki farklı kümenin hiçbirinde bulunan bir öğe yoktur . Ancak, buna benzer aranabilir sonuçlara çok benziyor:

CrossJoinUnionUnion3

Referans için CROSS JOINs için aranabilir bir sonuç Tutorialgateway'de görülebilir . INTERSECTION, Tıpkı bunun gibi, boştur.

İÇ BİRLEŞİM

Bir öğenin değeri JOINduruma bağlıdır . Bunu, her satırın o koşula özgü hale gelmesi koşuluyla temsil etmek mümkündür. Anlam id=xyalnızca bir satır için geçerlidir . Table A( citizen) öğesindeki bir satır , koşul altında table B( postalcode) içindeki birden çok satırla eşleştiğinde JOIN, sonuç şu sorunlarla aynı olur CROSS JOIN: Satırın birden çok kez temsil edilmesi gerekir ve küme teorisi bunun için gerçekten yapılmaz. Teklik koşulu altında, diyagram yine de işe yarayabilir, ancak JOINkoşulun diyagramdaki bir öğenin yerleşimini belirlediğini unutmayın . Sadece JOINsürüş için sadece sıranın geri kalanı ile durumun değerlerine bakmak :

InnerJoinIntersection - Dolgulu

Bu gösterim, a'yı INNER JOINbir ON 1 = 1koşula dönüştüren bir durum kullanıldığında tamamen parçalanır CROSS JOIN.

Kendiliğinden JOIN, satırlar aslında her iki tabloda da kimlik unsurlarıdır, ancak tabloları her ikisi olarak temsil eder Ave Bçok uygun değildir. Örneğin ortak bir öz JOINbir öğe yapar koşulu Aeşleşen bir olmak farklı B elemanı olup ON A.parent = B.child, eşleşmeyi yapma Aiçin Bayrı unsurları. Buna benzer örneklerden SQL:

SELECT *
  FROM citizen c1
  JOIN citizen c2 ON c1.id = c2.leader

SelfJoinResult

Anlam Smith, hem Green hem de Jensen'ın lideridir.

DIŞ KATILIM

Yine, bir satırın diğer tablodaki satırlarla birden fazla eşleşmesi olduğunda sorunlar başlar. Bu daha karmaşıktır çünkü OUTER JOINboş kümeyle eşleşecek şekilde olabilir. Ancak küme teorisinde, herhangi bir kümenin Cve boş bir kümenin birliği her zaman sadecedır C. Boş küme hiçbir şey eklemez. Bunun temsili LEFT OUTER JOINgenellikle sadece bir eşleşme olup olmadığına bakılmaksızın Aiçerideki satırların Aseçildiğini göstermek için tümünü gösterir B. Ancak "eşleşen elemanlar" yukarıdaki çizim ile aynı problemlere sahiptir. Duruma bağlıdır. Ve boş set şu şekilde dolaşmış gibi görünüyor A:

LeftJoinIntersection - Dolgulu

NEREDE yan tümcesi - mantıklı

CROSS JOINAy'da Smith ve posta kodu ile tüm satırları bulma :

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   AND p.area = 'Moon';

Nerede - sonuç

Şimdi Venn diyagramı yansıtmak için kullanılmıyor JOIN. YalnızcaWHERE fıkra için kullanılır :

Nerede

..ve bu mantıklı.

INTERSECT ve UNION mantıklı olduğunda

INTERSECT

Açıklandığı gibi bir INNER JOINgerçekten bir değil INTERSECT. Ancak INTERSECTs, ayrı sorguların sonuçlarında kullanılabilir. Burada bir Venn diyagramı mantıklıdır, çünkü ayrı sorgulardan öğeler aslında sonuçlardan sadece birine veya her ikisine ait satırlardır. Kesişim, yalnızca satırın her iki sorguda da bulunduğu yerlerde sonuçları döndürecektir. Bu SQL, yukarıdaki satırla aynı satırla sonuçlanır WHEREve Venn diyagramı da aynı olur:

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';

BİRLİK

An OUTER JOINbir değil UNION. Bununla birlikte , her iki s'yi birleştiren tüm sonuçların geri dönüşüyle ​​sonuçlanan UNIONaynı koşullar altında çalışır :INTERSECTSELECT

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';

eşdeğer:

SELECT *
  FROM citizen          c
 CROSS JOIN postalcode  p
 WHERE c.name = 'Smith'
   OR p.area = 'Moon';

..ve sonuç verir:

Birliği - Sonuç

Ayrıca burada bir Venn şeması mantıklı:

BİRLİK

Geçerli olmadığında

Bir önemli not bunlar yalnızca eser iki SEÇ yıllardan sonuçların yapısı bir karşılaştırma veya birliktelik sağlayarak, aynı olduğunda olmasıdır. Bu ikisinin sonuçları bunu etkinleştirmeyecektir:

SELECT *
  FROM citizen
 WHERE name = 'Smith'
SELECT *
  FROM postalcode
 WHERE area = 'Moon';

sonuçları birleştirmek için ..trying UNIONa verir

ORA-01790: expression must have same datatype as corresponding expression

Daha fazla ilgi için venn diyagramı olarak JOIN ve sql birleşimlerini açıklarken Venn Diyagramlarına NO deyin . Her ikisi de kapsar EXCEPT.


1

Burada çok doğru ilişkisel cebir örnekleri ile bir çok iyi cevap var . İşte SQL kodlama ikilemleri ile amatör veya acemi kodlayıcılar için yararlı olabilecek çok basitleştirilmiş bir cevap.

Temel olarak, çoğu zaman sorgular JOINiki duruma kadar kaybolur:

Bir SELECTveri alt kümesi için A:

  • kullanmak INNER JOINilgili veriler ne zaman BAradığınız ZORUNLULUK veritabanı tasarımı başına var;
  • veritabanı tasarımı başına MIGHT veya MIGHT NOT aradığınız LEFT JOINilgili veriler olduğunda kullanın .B

1

Arasındaki fark inner joinve outer joinaşağıdaki gibidir:

  1. Inner joineşleşen tablolara göre birleştirilen bir birleştirmedir, oysa outer joineşleşen ve eşleşmeyen demetlere göre birleştirilen bir birleştirmedir.
  2. Inner joineşleşmeyen satırı, eşleşmeyen satırın atlandığı iki tablodan birleştirirken, iki tablodaki outer joinsatırları birleştirir ve eşleşmeyen satırlar null değeriyle doldurulur.
  3. Inner joinkavşak operasyonu outer joingibi, sendika operasyonu gibidir.
  4. Inner joiniki tip, outer joinüç tiptir.
  5. outer joindaha hızlıdır inner join.

1
Bir dış birleşim sonucu iç birleşim ile aynıdır, ancak bazı ek satırlar, bu nedenle dış birleşimin neden daha hızlı olacağını düşündüğüm hakkında hiçbir fikrim yok. Ayrıca bu iç birleşimin "iki türü" nedir? Sanırım dış için tam, sol ve sağdan bahsediyorsun?
Martin Smith

1
@ M.achaibou Lütfen gereksiz format değişiklikleri yapan düzenlemeler yapmayın. Kodda kullanılmadıkça işleçlerin adları kod değildir. Lütfen anlam göndermek için değişiklik yapmayın, yazara yorum gönderin. Temsilciniz yoksa, o zamana kadar bekleyin. Poster bunu onayladı ancak lütfen bu tür düzenlemeler yapmayın. PS Dış birleşim iç birleşimden daha hızlı değil.
philipxy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.