MySQL: Birleştirme türlerinin hızlı dökümü [yinelenen]


157

MySQL birleşim türlerinin hızlı bir dökümünü istiyorum. Bunları biliyorum, gerisi ne demek istediğinden emin değilim.

  • virgülle ayrılmış (bu tam olarak ne için kısadır?):SELECT * FROM a, b WHERE b.id = a.beeId AND ...
  • b'de eşleşme olmasa bile a'dan gelen bilgileri göster: SELECT * FROM a LEFT OUTER JOIN b ON b.id = a.beeId WHERE ...

Diğer katılır görülen, ama onları farklı, ne yapar ne olduğunu bilmek istiyorum var INNER/ OUTERekleme gelmez LEFTşeyleri değiştirmek.

Katılmaların nasıl çalıştığını zaten biliyorum, sadece başka tür birleşimler olup olmadığını veya aynı sonucu elde etmenin sadece farklı yolları olup olmadığını bilmek istiyorum.

Yanıtlar:


27

Yorumunuza dayanarak, her birinin basit tanımları en iyi W3Schools'ta bulunur Her türün ilk satırı, birleştirme türünün kısa bir açıklamasını verir

  • JOIN: Her iki tabloda da en az bir eşleşme olduğunda satırları döndür
  • SOL BİRLEŞTİR: Sağ tabloda eşleşme olmasa bile tüm satırları soldaki tablodan döndür
  • SAĞ BİRLEŞTİR: Sol tabloda eşleşme olmasa bile tüm satırları sağ tablodan döndür
  • FULL JOIN: Tablolardan birinde bir eşleşme olduğunda satırları döndür

SON DÜZENLEME

Özetle, verdiğiniz virgülle ayrılmış örnek

SELECT * FROM a, b WHERE b.id = a.beeId AND ...

a ve b tablolarından virgül ve tabloları ayıran her kaydı seçiyorsa, bu, aşağıdaki gibi sütunlarda da kullanılabilir

SELECT a.beeName,b.* FROM a, b WHERE b.id = a.beeId AND ...

Daha sonra, b.id sütununun ve a.beeId sütununun örneğinizde eşleştiği satırdaki talimatlı bilgileri alır. Böylece örneğinizde, b.id'in a.beeId değerine eşit olduğu a ve b tablolarından tüm bilgileri alacaktır. Örneğimde, b tablosundaki tüm bilgiler ve yalnızca b.id a.beeId değerine eşit olduğunda yalnızca a.beeName sütunundaki bilgiler alınacaktır. Bir AND cümlesi olduğunu da unutmayın, bu sonuçlarınızı hassaslaştırmanıza yardımcı olacaktır.

Bazı basit öğreticiler ve mySQL birleşimleri ve sol birleşimlerle ilgili açıklamalar için Tizag'ın mySQL öğreticilerine bir göz atın. Ayrıca oldukça iyi olan birleşimler hakkında daha fazla bilgi için Keith J.Brown'un web sitesine de bakabilirsiniz .

umarım bu sana yardımcı olur


Bunları zaten biliyordum. Aslında var olan birleştirme türlerini arıyordum. Üzgünüm, bildiklerim hakkında net değildim. Ancak kısa bir özet almak için uzun belgeler aramıyordum.
Bryan Field

Cevabın başka bir referansı ... daha çok istediğin şey olabilir dostum.
Ryan

Bu düzenleme için +1. Bazı insanlar gibi görünen W3Schools'a karşı önyargılı değilim. Belki de kötü tarafları pek görmedim ya da belki de sadece "kutsal bir savaş". Ayrıca, W3Schools'un içeriğinde düzenledim, umarım aldırmazsınız, ancak istediğiniz düzenlemeleri yapmaktan çekinmeyin. Kabul edilen cevaptaki tüm görseller güzel, ancak bazıları aslında aynı birleşmenin varyasyonları. Bu iyi bir alternatif.
Bryan Field

Teşekkürler George, düzenlemenin doğru olması koşuluyla hiç umrumda değil! İnsanların kendileri için doğru olan kaynakları, az ya da çok bilgiyi, çok sayıda örneği ya da hiçbirini bulması gerektiğine inanıyorum. W3Schools doğru ve özlüdür, iyi örneklere sahip olma eğilimindedirler, Tizag benzerdir. Sakin olun dostum
Ryan

2
mysql'de FULL JOIN yoktur, bu yüzden bu bağlantılar çok kullanışlı değildir.
Eter

13

Bunun gibi 2 tablo var:

> SELECT * FROM table_a;
+------+------+
| id   | name |
+------+------+
|    1 | row1 |
|    2 | row2 |
+------+------+

> SELECT * FROM table_b;
+------+------+------+
| id   | name | aid  |
+------+------+------+
|    3 | row3 |    1 |
|    4 | row4 |    1 |
|    5 | row5 | NULL |
+------+------+------+

INNER JOIN her iki tabloya da önem veriyor

INNER JOIN her iki tabloya da önem verir, bu nedenle yalnızca her iki tabloda bir tane varsa bir satır alırsınız. Birden fazla eşleşen çift varsa, birden çok satır alırsınız.

> SELECT * FROM table_a a INNER JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
+------+------+------+------+------+

Her iki tabloyu önemsediğinden, siparişi tersine çevirirseniz INNER JOIN ile hiçbir fark yaratmaz:

> SELECT * FROM table_b b INNER JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
+------+------+------+------+------+

Aynı satırları alırsınız, ancak tabloları farklı bir sırayla belirttiğimiz için sütunlar farklı bir sıradadır.

LEFT JOIN sadece ilk masayı önemsiyor

LEFT JOIN, verdiğiniz ilk tabloyu önemsiyor ve ikincisini fazla önemsemiyor, bu nedenle ikinci tabloda karşılık gelen bir satır olmasa bile, her zaman ilk tablodaki satırları alırsınız:

> SELECT * FROM table_a a LEFT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
|    2 | row2 | NULL | NULL | NULL |
+------+------+------+------+------+

Yukarıda, bazıları tablo b'deki herhangi bir şeyle eşleşmese de tüm table_a satırlarını görebilirsiniz, ancak tüm table_b satırlarını değil - yalnızca table_a'daki bir şeyle eşleşen satırları görebilirsiniz.

Tabloların sırasını tersine çevirirsek, LEFT JOIN farklı davranır:

> SELECT * FROM table_b b LEFT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
|    5 | row5 | NULL | NULL | NULL |
+------+------+------+------+------+

Şimdi tüm table_b satırlarını alıyoruz, ancak yalnızca eşleşen table_a satırlarını alıyoruz.

RIGHT JOIN sadece ikinci masayı önemsiyor

a RIGHT JOIN btam olarak aynı satırları alır b LEFT JOIN a. Tek fark, sütunların varsayılan sırasıdır.

> SELECT * FROM table_a a RIGHT JOIN table_b b ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | id   | name | aid  |
+------+------+------+------+------+
|    1 | row1 |    3 | row3 | 1    |
|    1 | row1 |    4 | row4 | 1    |
| NULL | NULL |    5 | row5 | NULL |
+------+------+------+------+------+

Bu, table_b LEFT JOIN table_aSOL GİRİŞ bölümünde gördüğümüz satırlarla aynı .

Benzer şekilde:

> SELECT * FROM table_b b RIGHT JOIN table_a a ON a.id=b.aid;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    4 | row4 | 1    |    1 | row1 |
| NULL | NULL | NULL |    2 | row2 |
+------+------+------+------+------+

İle aynı satırlardır table_a LEFT JOIN table_b.

Hiçbir katılma size her şeyin kopyalarını verir

Tablolarınızı virgülle ayrılmış olarak hiçbir JOIN yan tümcesi olmadan yazarsanız, ikinci tablonun her satırının yanına yazılan ilk tablonun her satırını her olası kombinasyonda alırsınız:

> SELECT * FROM table_b b, table_a;
+------+------+------+------+------+
| id   | name | aid  | id   | name |
+------+------+------+------+------+
|    3 | row3 | 1    |    1 | row1 |
|    3 | row3 | 1    |    2 | row2 |
|    4 | row4 | 1    |    1 | row1 |
|    4 | row4 | 1    |    2 | row2 |
|    5 | row5 | NULL |    1 | row1 |
|    5 | row5 | NULL |    2 | row2 |
+------+------+------+------+------+

(Bu benim blog yazımdan SQL birleştirme türleri örnekleri )


@Anu Bu cevap, çoğu cevaptakiyle aynı parçalanmış eksik açıklamalara sahiptir. Aslında, girdilerin bir işlevi olarak çıktının ne olduğunu söylemez. Ayrıca, önerilen kopyadaki hemen hemen her yanıta ve her iki sayfadaki yorumlarıma bakın. Ayrıca cevabımı da görün. PS Ben coincientally sadece dün yeniden gözden geçirme düzenleme boyutu gördüm (Tabii ki Meta Stack Overflow & Meta Stack Exchange de daha birçok ilgili mesajlar vardır .)
philipxy

11

Tam Dış birleşim mysql'de mevcut değil, sol ve sağ birleşim kombinasyonunu kullanmanız gerekebilir.

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.