Ayrıca nasıl LEFT JOIN
, RIGHT JOIN
ve FULL JOIN
fit?
Ayrıca nasıl LEFT JOIN
, RIGHT JOIN
ve FULL JOIN
fit?
Yanıtlar:
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
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.
on
satırları koruyarak, 1. adımdaki tüm satırlara göre cümleyi değerlendirintrue
(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.
Kaynak Tabloları
İlk olarak bir CROSS JOIN
(AKA Kartezyen Ürünü) ile başlayın . Bu bir ON
cü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
İç ve Dış birleşimler "AÇIK" yantümceye sahiptir.
A.Colour, B.Color INNER JOIN B'den A.Colour = B.Colour ÜZERİNDEN SEÇİN
Yukarıdaki klasik equi birleştirme.
İç 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 .
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.
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 NULL
değerlerle korunur. sağ sütunlar.
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 NULL
Test için nullable olmayan veya birleştirme koşulunun NULL
bu kalıbın düzgün çalışması ve herhangi bir NULL
değ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.
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.
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.
Çapraz birleştirmedeki hiçbir satır 1=0
yü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.
Önceki sorguda yapılan küçük bir değişiklikle UNION ALL
, iki tablodan birinin simülasyonu yapılabilir .
Not o WHERE
fı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 ...
... 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.
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
SQLFiddle.com'da canlı olarak yayınlanan bu örneklere bakın .
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:
İç 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:
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:
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:
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.
Yalnızca eşleşen satırları alın, yani A intersect B
.
SELECT *
FROM dbo.Students S
INNER JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
İlk tablodaki tüm kayıtları ve ikinci tablodaki birleştirilmiş anahtarlarla eşleşen kayıtları seçin.
SELECT *
FROM dbo.Students S
LEFT JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
İkinci tablodaki tüm kayıtları ve ilk tablodaki birleştirilmiş anahtarlarla eşleşen kayıtları seçin.
SELECT *
FROM dbo.Students S
FULL JOIN dbo.Advisors A
ON S.Advisor_ID = A.Advisor_ID
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
İç 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.
İç 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ş detayları
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
.
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 ASC
başarı ile (MySQL). Ek koşullardan emin değildim, iyi
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 :
Ş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_id
birbirine 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:
INNER JOIN
Eş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 LEFT
veya 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.
Bu, her türlü birleştirme için iyi bir diyagramatik açıklamadır
kaynak: http://ssiddique.info/understanding-sql-joins-in-easy-way.html
INNER JOIN
iki 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 JOIN
ve RIGHT JOIN
aynı. 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 JOIN
ve RIGHT OUTER JOIN
çoğaltma olmadan birleşimidir .
Cevap her birinin anlamında, sonuçlarda.
Not:
içinde veyaSQLite
yoktur . Ve ayrıca orada yok .RIGHT OUTER JOIN
FULL OUTER JOIN
MySQL
FULL 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 JOIN
veya 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.id
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] 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;).
full outer join
.
İç 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ş).
INNER JOIN
iki 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 JOIN
ile aynıdır INNER JOIN
, ancak NULL
ResultSet'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 Null
eşleşmeyen verileri .FULL JOIN
= INNER JOIN
+ Hem sağ hem de sol tablolarda Null
eşleşmelerle eşleşmeyen veriler .INNER JOIN
ve OUTER JOIN
biz ö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
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 JOIN
farklı 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:
INNER JOIN
olduğundan daha yavaş LEFT JOIN
, Ve insanlar LEFT JOIN
yerine beklenmedik sonuçları kaldırmak için INNER JOIN
bir ekleyerek kullanabilirsiniz ;). WHERE
NULL
INNER
daha yavaş?
Ç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 TableB
olduğunu veya OUTER JOIN
aslında bir birleşimden ziyade bir birlik olduğunu gösterdiğini düşünmüyorum :
TableA a LEFT OUTER JOIN TableB b
birlikteTableB B RIGHT OUTER JOIN TableA a
Hassas algoritması INNER JOIN
, LEFT/RIGHT OUTER JOIN
aşağıdaki gibidir:
a
(a, b[i])
ON ...
Her bir çift için maddeyi değerlendirin :ON( a, b[i] ) = true/false?
true
, birleştirilmiş satırı döndürün (a, b[i])
.Outer Join
bir (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:
... ON T1.title = T2.title AND T1.version < T2.version
(=> bu yayını örnek kullanım olarak görün: Yalnızca bir sütunda maksimum değeri olan satırları seçin )... ON T1.y IS NULL
... ON 1 = 0
(tıpkı örnek olarak)Not: Sol Birleştirme = Sol Dış Birleştirme, Sağ Birleştirme = Sağ Dış Birleştirme.
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ı
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.
Ö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.
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.
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
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
.
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
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.
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
İç 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
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.
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
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
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.
Birleşimlerin Avantajları
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
Çoğunlukla sql sorgularında JOIN olarak yazılır . Yalnızca tablolar arasındaki eşleşen kayıtları döndürür.
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, Jose
yazdırılan değildir EMP 's dept_id olarak çıktısında 6
Bölümü tablosunda bir eşleşme bulmak. Benzer şekilde HR
ve Emp tablosunda bir eşleşme bulamadıklarından R&D
satırlar Departman tablosundan yazdırılmaz .
INNER JOIN veya sadece JOIN, yalnızca eşleşen satırları döndürür.
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.
HR
ve dept_id üzerindeki Emp tablosunda bir eşleşme bulamadıklarından R&D
satı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 .
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 JOIN
ve LEFT OUTER JOIN
.
Bu iki tablo, JOIN
aşağıdaki örneklerin temsili için bir temel oluşturur :
SELECT *
FROM citizen
CROSS JOIN postalcode
Sonuç, tüm kombinasyonların Kartezyen ürünleri olacaktır. Hiçbir JOIN
koşul gerekmez:
INNER JOIN
basitçe aynıdır: JOIN
SELECT *
FROM citizen c
JOIN postalcode p ON c.postal = p.postal
Sonuç, gerekli JOIN
koşulu karşılayan kombinasyonlar olacaktır :
LEFT OUTER JOIN
aynıdır LEFT JOIN
SELECT *
FROM citizen c
LEFT JOIN postalcode p ON c.postal = p.postal
Sonuç, citizen
maçlar olmasa bile her şey olacaktır postalcode
. Yine bir JOIN
koşul gereklidir:
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;
JOIN
Ve ile oynarken bulanık sınırlarWHERE
CROSS JOIN
Genel 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 JOIN
sonucu almak için kullanmak için arka arkaya LEFT OUTER JOIN
ekleme gibi hileler gerekir NULL
. Atlandı.
INNER JOIN
kartezyen 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 JOIN
Sonuç almak için kullanmak LEFT OUTER JOIN
da hileler gerektirir. Atlandı.
LEFT JOIN
Genel 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 JOIN
Genel 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
"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 ( citizen
tablo) ve küme B
, postalcode
aşağıdaki tartışmada sağdaki seti ( tablo) temsil eder .
Her iki setlerinde her eleman biz gerek, yani diğer sette her eleman ile eşleştiği A
her miktarına B
unsurları ve B
her miktarına A
dü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. UNION
Toplamda 7 sırasıdır. Ancak ortak bir SQL
sonuç kümesi için uyumsuzdurlar . Ve bu hiç de böyle değil CROSS JOIN
:
Bunu şöyle temsil etmeye çalışıyorum:
..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:
Referans için CROSS JOIN
s için aranabilir bir sonuç Tutorialgateway'de görülebilir . INTERSECTION
, Tıpkı bunun gibi, boştur.
Bir öğenin değeri JOIN
duruma 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=x
yalnı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 JOIN
koşulun diyagramdaki bir öğenin yerleşimini belirlediğini unutmayın . Sadece JOIN
sürüş için sadece sıranın geri kalanı ile durumun değerlerine bakmak :
Bu gösterim, a'yı INNER JOIN
bir ON 1 = 1
koş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 A
ve B
çok uygun değildir. Örneğin ortak bir öz JOIN
bir öğe yapar koşulu A
eşleşen bir olmak farklı B elemanı olup ON A.parent = B.child
, eşleşmeyi yapma A
için B
ayrı unsurları. Buna benzer örneklerden SQL
:
SELECT *
FROM citizen c1
JOIN citizen c2 ON c1.id = c2.leader
Anlam Smith, hem Green hem de Jensen'ın lideridir.
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 JOIN
boş kümeyle eşleşecek şekilde olabilir. Ancak küme teorisinde, herhangi bir kümenin C
ve boş bir kümenin birliği her zaman sadecedır C
. Boş küme hiçbir şey eklemez. Bunun temsili LEFT OUTER JOIN
genellikle sadece bir eşleşme olup olmadığına bakılmaksızın A
içerideki satırların A
seç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
:
CROSS JOIN
Ay'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';
Şimdi Venn diyagramı yansıtmak için kullanılmıyor JOIN
. YalnızcaWHERE
fıkra için kullanılır :
..ve bu mantıklı.
Açıklandığı gibi bir INNER JOIN
gerçekten bir değil INTERSECT
. Ancak INTERSECT
s, 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 WHERE
ve 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';
An OUTER JOIN
bir değil UNION
. Bununla birlikte , her iki s'yi birleştiren tüm sonuçların geri dönüşüyle sonuçlanan UNION
aynı koşullar altında çalışır :INTERSECT
SELECT
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:
Ayrıca burada bir Venn şeması mantıklı:
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 UNION
a 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
.
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 JOIN
iki duruma kadar kaybolur:
Bir SELECT
veri alt kümesi için A
:
INNER JOIN
ilgili veriler ne zaman B
Aradığınız ZORUNLULUK veritabanı tasarımı başına var;LEFT JOIN
ilgili veriler olduğunda kullanın .B
Arasındaki fark inner join
ve outer join
aşağıdaki gibidir:
Inner join
eşleşen tablolara göre birleştirilen bir birleştirmedir, oysa outer join
eşleşen ve eşleşmeyen demetlere göre birleştirilen bir birleştirmedir.Inner join
eşleşmeyen satırı, eşleşmeyen satırın atlandığı iki tablodan birleştirirken, iki tablodaki outer join
satırları birleştirir ve eşleşmeyen satırlar null değeriyle doldurulur.Inner join
kavşak operasyonu outer join
gibi, sendika operasyonu gibidir.Inner join
iki tip, outer join
üç tiptir.outer join
daha hızlıdır inner join
.