SOL DIŞ BİRLEŞTİRME sol tabloda var olandan nasıl daha fazla kayıt döndürebilir?


165

Sol tablodan tüm sonuçları ve çok daha büyük bir tablodan bazı ek bilgileri döndürmek için çok temel bir SOL GİRİŞ var. Soldaki tablo 4935 kayıt içeriyor ancak ek bir tabloya katıldığımda kayıt sayısı önemli ölçüde artıyor.

Bildiğim kadarıyla, bir SOL DIŞ BİRLEŞTİRME, sol tablodaki tüm kayıtları sağ tablodan eşleşen kayıtlarla ve eşleştirilemeyen herhangi bir satır için boş değerlerle döndürecek şekilde mutlak bir müjde, Sol tabloda var olandan daha fazla satır döndürmek imkansız olmalı, ancak hepsi aynı oluyor!

SQL Sorgusu aşağıdaki gibidir:

SELECT     SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM         SUSP.Susp_Visits LEFT OUTER JOIN
                      DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum

Belki de sözdiziminde bir hata yaptım ya da LEFT OUTER JOIN anlayışım eksik, umarım birisi bunun nasıl olabileceğini açıklayabilir?

dipnot

Büyük cevaplar için teşekkürler, SOL DIŞ BİRLEŞTİRMELER anlayışım şimdi çok daha iyi, ancak herkes sadece bu tabloda değiştirilebilecek bir yol önerebilir, böylece sadece sol tabloda var olduğu kadar çok kayıt döndürürüm?

Bu sorgu yalnızca bir rapor oluşturmak içindir ve yinelenen eşleşmeler yalnızca konuları karıştırır.

/ Postscript


5
"Sol tabloda var olan sayıda kayıt döndürülmesini" sağlamak için, birden çok eşleşme olup olmadığını seçmek üzere sağ taraftan hangi satırı belirtmeniz gerekir.
AK

1
bunu nasıl belirlersin? İlk maçın iade edilmesini istiyorum.
Simon Cross

1
ilk maçın ne anlama geldiğini tanımlamanız gerekir. En eski kaydı mı, en yüksek kimliği olan kaydı mı yoksa ne istiyorsun?
HLGEM

1
Ek tabloda birincil anahtarla eşleşirseniz ifadeniz doğrudur.
Prageeth Godage

Sık sık böyle bir kaynağı kullanmak bu sorgu oluştururken kısa notlar olarak. Bağlantı hiç ölmezse, sadece google sql join ; bunlar farklı birleştirme türlerinin Venn diyagramlarıdır.
Zimano

Yanıtlar:


190

LEFT OUTER JOIN, SAĞ tablo ile birleştirilen SOL tablodaki tüm kayıtları mümkün olduğunda döndürecektir.

Yine de eşleşmeler varsa, eşleşen tüm satırları yine de döndürür, bu nedenle, SOL'da, SAĞ'daki iki satırla eşleşen bir satır, tıpkı bir INNER JOIN gibi, iki ROWS olarak döner.

DÜZENLEME: Düzenlemenize yanıt olarak, sorgunuza biraz daha baktım ve yalnızca LEFT tablosundan veri döndürüyormuşsunuz gibi görünüyor. Bu nedenle, yalnızca LEFT tablosundan veri istiyorsanız ve LEFT tablosundaki her satır için yalnızca bir satır döndürülmesini istiyorsanız, bir JOIN gerçekleştirmeniz gerekmez ve doğrudan LEFT tablosundan bir SELECT yapabilirsiniz.


1
Sağ masaya katılmanın sebebi, soldan sadece sağ tabloda en az bir kayıt olduğu için kayıtlar almaktı, ancak açıklama için çok teşekkür ederim.
Jay Wilde

125
Table1                Table2
_______               _________
1                      2
2                      2
3                      5
4                      6

SELECT Table1.Id, Table2.Id FROM Table1 LEFT OUTER JOIN Table2 ON Table1.Id=Table2.Id

Sonuçlar:

1,null
2,2
2,2
3,null
4,null

1
Çok basit ama yine de çok güçlü.
kiradotee

39

İmkansız değil. Sol tablodaki kayıt sayısı, döndüreceği minimum kayıt sayısıdır. Sağ tabloda sol tabloda bir kayıtla eşleşen iki kayıt varsa, iki kayıt döndürür.


12

Postscript'inize yanıt olarak, bu ne istediğinize bağlıdır.

Birleştirme koşulu için birden çok eşleşme olduğu için sol tablonuzdaki her satır için birden fazla satır (olası) alıyorsunuz. Toplam sonuçlarınızın, sorgunun sol kısmında olduğu gibi aynı sayıda satıra sahip olmasını istiyorsanız, birleştirme koşullarınızın 1'e 1 eşleşmesine neden olduğundan emin olmanız gerekir.

Alternatif olarak, gerçekte ne istediğinize bağlı olarak toplama işlevlerini kullanabilirsiniz (örneğin sadece sağ kısımdan bir dize istiyorsanız, o sol satır için sağ taraf sonuçlarının virgülle ayrılmış bir dizesi olan bir sütun oluşturabilirsiniz.

Dış birleşimden yalnızca 1 veya 2 sütuna bakıyorsanız, 1 sonuç garanti edeceğiniz için skaler bir alt sorgu kullanmayı düşünebilirsiniz.


4
Sol tablodan sadece satırların nasıl döndürüleceğine dair öneriler sunduğu için bu iyi bir cevaptır.
karns

9

Sol tablodaki her kayıt, sağ tabloda eşleşen kayıtların olduğu kadar çok sayıda döndürülür - en az 1, ancak kolayca 1'den fazla olabilir.


8

SOL OUTER JOIN (INNER JOIN (normal birleştirme) gibi sol tablodaki her satır için sağ tabloda bulduğu kadar çok sonuç döndürür. Bu nedenle, N x M'ye kadar, N'nin sol tablodaki satır sayısı ve M sağ tablodaki satır sayısı olan birçok sonuç elde edebilirsiniz.

LEFT OUTER JOIN'de minimum sonuç sayısının daima en az N olacağı garanti edilir.


1
Satır sayısı N x M eşit olduğunda ve aklıma gelen tek gerçek durumun N veya M 1 olduğu zaman olduğunu düşünmeye başladım.
BartoszMiller

2
Hayır. Birleştirme koşulunu yalnızca kilit eşitlik birleşimi olarak düşünmemelisiniz. Tarih aralıkları, eşitsizlikler, vb. Gibi rasgele bir durum olabilir. İki uç durum: (a) N satırının M satırları arasında tek bir eşleşmesi yoktur, daha sonra NULL'larla eşleşen N satırlarında sol dış birleşim sonuçları oluşur. (b) N satırın her biri tüm M satırlarıyla eşleşir, sonuç N x M satır ayarlanır.
topchef

1
Haklısın, katılmaları sadece temel eşitlik açısından düşünüyordum. Örneğini "case b" den sevdim. "N satırının her biri tüm M satırlarıyla eşleşir" in N x M satırları döndürüldüğünde genel bir reçete olduğuna inanıyorum;
BartoszMiller


6

Sol dış birleşim içeren bir sorgunun "sağ taraf" tablosunda bir nerede yan tümceniz varsa dikkat edin ... Sağ yanda nerede yan tümcesini karşılayan bir kayıt yoksa, "sol tarafın karşılık gelen kaydı" 'tablosu sorgunuzun sonucunda görünmeyecek ....


1
Daha sonra, ilgili LEFT OUTER JOIN öğesinin ON yan tümcesine koşulu eklemelisiniz.
Mik

6

Sağ taraftan herhangi bir satıra ihtiyacınız varsa

SELECT SuspReason, SiteID FROM(
    SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER()
    OVER(PARTITION BY SUSP.Susp_Visits.SiteID) AS rn
    FROM SUSP.Susp_Visits
    LEFT OUTER JOIN DATA.Dim_Member ON SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
) AS t
WHERE rn=1

ya da sadece

SELECT SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID
FROM SUSP.Susp_Visits WHERE EXISTS(
    SELECT DATA.Dim_Member WHERE SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum
)

1
DDL ve DML sağlamadığınız için test etmedim. Her neyse, ben MEVCUT istediğiniz olduğunu düşünüyorum. Şunu deneyin: SEPReason, SiteID FROM (SELUS SUSP.Susp_Visits.SuspReason, SUSP.Susp_Visits.SiteID, ROW_NUMBER () OVER (SUSP.Susp_Visits.SiteID SİPARİŞ SUSP.Susp_Visits.SiteID_RUSS_USS.SUSID_RUSS_USS FUSS.SUSID_RISS). JOIN DATA.Dim_Member AÇIK SUSP.Susp_Visits.MemID = DATA.Dim_Member.MembershipNum) oLARAK t WHERE rn = 1
AK

2

Her SUSP.Susp_Visits satırında DATA.Dim_Member tablosunda birden çok satır varmış gibi görünüyor.


2

Dim_Member'deki birden çok (x) satır Susp_Visits'teki tek bir satırla ilişkiliyse, sonuç kümesinde x satır olacaktır.

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.