Doğal birleşim ve iç birleşim arasındaki fark


Yanıtlar:


250

INNER JOIN ve NATURAL JOIN arasındaki önemli bir fark döndürülen sütun sayısıdır.

Düşünmek:

TableA                           TableB
+------------+----------+        +--------------------+    
|Column1     | Column2  |        |Column1  |  Column3 |
+-----------------------+        +--------------------+
| 1          |  2       |        | 1       |   3      |
+------------+----------+        +---------+----------+

INNER JOINSütun1'de üzerinde TableA ve TABLEB arasında dönecektir

SELECT * FROM TableA AS a INNER JOIN TableB AS b USING (Column1);
SELECT * FROM TableA AS a INNER JOIN TableB AS b ON a.Column1 = b.Column1;
+------------+-----------+---------------------+    
| a.Column1  | a.Column2 | b.Column1| b.Column3|
+------------------------+---------------------+
| 1          |  2        | 1        |   3      |
+------------+-----------+----------+----------+

NATURAL JOINSütun1'de üzerinde TableA ve TABLEB ait döner:

SELECT * FROM TableA NATURAL JOIN TableB
+------------+----------+----------+    
|Column1     | Column2  | Column3  |
+-----------------------+----------+
| 1          |  2       |   3      |
+------------+----------+----------+

Tekrarlanan sütundan kaçınılır.

(Standart dilbilgisinden AFAICT olarak, doğal bir birleştirmede birleştirme sütunlarını belirtemezsiniz; birleştirme kesinlikle ad tabanlıdır. Ayrıca bkz . Wikipedia .)

( İç bir hile var çıkışını katılmak; a.ve b.parça sütun adlarında olmaz; sadece olurdu column1, column2, column1, column3başlıkları olarak. )


2
İki tablo TableA (Sütun1, Sütun2) ve TabloB (Sütun2, Sütun3) var.
2 8

16
Çıktıdaki sütunları daraltmak, doğal birleştirmenin en az önemli yönüdür. Bilmeniz gerekenler, (A) aynı addaki alanlara otomatik olarak katılır ve (B) en az beklediğinizde sizi fahişe eder. Benim dünyamda doğal bir birleşim kullanmak işten çıkarılma nedenidir.

8
@JonofAllTrades Neyin tam olarak NATURAL JOINmahvedeceğini, neden beklenmedik olduğunu ve hangi dünyada olduğunuzu açıklayabilir misiniz?
Bryson

36
Bu, user166390'ın cevabında bir şekilde ele alınmaktadır. Diyelim ki Customersve arasında doğal bir birleşim Employeesvar EmployeeID. Employeesayrıca bir ManagerIDalanı var. Herşey yolunda. Sonra, bir gün, birisi masaya bir ManagerIDalan ekler Customers. Birleştirme işleminiz kesilmeyecek (bu bir merhamet olacaktır), bunun yerine şimdi ikinci bir alan içerecek ve yanlış çalışacaktır . Böylece, görünüşte zararsız bir değişiklik sadece uzaktan ilgili bir şeyi kırabilir. ÇOK KÖTÜ. Doğal birleşmenin tek tarafı biraz yazarak tasarruf etmek ve dezavantajı önemli.

2
@Jonathan, Cevabınızla ilgili olarak SELECT * FROM TableA INNER JOIN TableB USING (Column1)4 sütun verdiğini söylediniz . Bunun nedeni doğru değildir SELECT * FROM TableA INNER JOIN TableB USING (Column1)ve SELECT * FROM TableA NATURAL JOIN TableBeşit ikisi de vermek 3 sütun.
Pacerier

81
  • Bir birleştirilmiş tabloda uygun satır ilk tablosundan bir satır için gerekli olan bir döndürülecek katılmak
  • Bir dış birleştirme birleştirilmiş tabloda eşleşen satır edildiği bir değil döndürülecek birinci tablonun bir satırı için gerekli
  • Bir doğal katılmak bir (ya sahip olabilir katılmak olduğunu natural leftveya natural right) olmak katılmak kriterlerini varsayar nerede hem tablo maçında aynı adlı sütunlar

Veba gibi doğal eklemleri kullanmaktan kaçınırdım, çünkü doğal eklemler:

  • olup , standart bir SQL [SQL 92] ve bu nedenle (çoğu SQL kodlayıcı) tarafından özel olarak okunabilir olup, taşınabilir ve muhtemelen çeşitli araçlar / kütüphaneler tarafından desteklenen
  • bilgilendirici değil; şemaya başvurmadan hangi sütunların birleştirildiğini söyleyemezsiniz
  • birleştirme koşullarınız şema değişikliklerine görünmez bir şekilde açıktır - birden çok doğal birleştirme sütunu varsa ve böyle bir sütun bir tablodan kaldırılırsa, sorgu yine de yürütülür, ancak muhtemelen doğru olmaz ve davranıştaki bu değişiklik sessiz olur
  • çabaya pek değmez; yazarken yalnızca 10 saniyeden tasarruf edersiniz

2
Dış için sol / sağdan bahsedilmesi gerektiğini düşünüyorum (dıştan hiç bahsedilmediğinden). Ama aksi halde, hoş ve özlü: sadece güzel örnek SQL kayıt diyagramlarını kaçırıyor.

2
DOĞAL SOL ve DOĞAL SAĞ da mevcuttur. Ama evet, yine de onlardan kaçının.
MatBailie

1
@ Bohemian, "Onları veba gibi önlemek" ile ilgili olarak, doğal birleşimler için kullanışlı oldukları gerçek kullanım durumları vardır. mariadb.com/kb/en/sql-99/natural-join "... Sıradan görünümlü" Kitaplar NATURAL JOIN Checkouts", yalnızca veritabanı adlandırma kuralları resmi ve zorunlu olduğunda mümkündür."
Pacerier

2
@sqlvovel Yorumunuzda çok yanlış var, özellikle yanlış. Üyelik sütunları olamaz "seçkin listede belirtilen" olmak. Doğal bir birleşimin tanımı, * tüm benzer adlı sütunlara * katılmaktır . MySQL doc'den: İki tablonun NATURAL [LEFT] JOIN ifadesi, her iki tabloda da bulunan tüm sütunları adlandıran bir INNER JOIN veya bir USING yan tümcesine sahip bir LEFT JOIN ile anlamsal olarak eşdeğer olarak tanımlanmıştır. . Ve başka bir şey - pratikte işe yaramaz, çünkü idher yerde ve katılmak için işe yaramaz; olağan yabancı anahtar isimleri tablename_id. Doğal birleşimler kötü, kötü, kötü bir fikirdir.
Bohemya

2
Sorgumda çift döndürülmüş sütun yok. NJ anlambiliminin avantajlarından biri, çoğaltılan sütunların hiçbir zaman döndürülmemesidir. Önceki sorgunuz da benimkinden "daha az güvenli" idi, çünkü t2'ye "a" adlı bir sütun eklenirse başarısız olur (diğer adın birleşim durumu belirsiz olduğundan). NJ'ye karşı önyargılarınızın, standart SQL'in düzgün bir şekilde desteklendiği bir üründe denemediğiniz gerçeğine dayandığından şüpheleniyorum. Buradaki soru MySQL değil SQL ile ilgili - oldukça farklı şeyler. Hala standart dışı olmasıyla ilgili cevabınızı düzeltmediniz.
nvogel

27

Doğal birleştirme, birleştirmenin basit olduğu ve aynı addaki alanlarla eşleştiği varsayımıyla, yazmaktan kaçınmak için sadece bir kısayoldur.

SELECT
  *
FROM
  table1
NATURAL JOIN
  table2
    -- implicitly uses `room_number` to join

Aynıdır...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON table1.room_number = table2.room_number

Ancak kısayol biçimiyle yapamayacağınız şey daha karmaşık birleşimler ...

SELECT
  *
FROM
  table1
INNER JOIN
  table2
    ON (table1.room_number = table2.room_number)
    OR (table1.room_number IS NULL AND table2.room_number IS NULL)

2
@JonathanLeffler - MySQL'de kesinlikle.
MatBailie

3
Tamam - ilginç. Sordum çünkü SQL standardı buna izin vermiyor gibi görünüyor (ancak uzantılar her zaman mümkündür).
Jonathan Leffler

Hangi DBMS bu standart dışı sözdizimi sağlar: NATURAL JOIN ... USING ()? Standart ya a NATURAL JOIN bdaa JOIN b USING (c)
ypercubeᵀᴹ

1
"yazmamak için sadece bir kısayol" bir yanlışlıktır. En önemli özelliği, yinelenen sütunlarla sonuçlanmamasıdır.
gün2

... örneğin, doğal birleştirme kullanan sorgunuzun sonucunda yalnızca bir sütun room_number, iç birleşimlerinizde ise iki sütun bulunur room_number.
gün2

13

SQL, ilişkisel modele pek çok açıdan sadık değildir. SQL sorgusunun sonucu, yinelenen adlara, 'anonim' (adsız) sütunlara, yinelenen satırlara, boş değerlere vb. Sahip sütunlara sahip olabileceğinden bir ilişki değildir. SQL, tabloları sütun sırası vb.

NATURAL JOINSQL'in arkasındaki fikir , ilişkisel modele daha sadık kalmayı kolaylaştırmaktır. NATURAL JOINİki tablonun sonucu, adıyla çoğaltılmış sütunlara sahip olacaktır, dolayısıyla anonim sütunlar içermeyecektir. Benzer şekilde UNION CORRESPONDINGve EXCEPT CORRESPONDINGSQL'in eski UNIONsözdizimindeki sütun sıralamasına bağımlılığını ele almak için sağlanmıştır .

Ancak, tüm programlama tekniklerinde olduğu gibi, disiplinin faydalı olmasını gerektirir. Başarılı bir gereksinim NATURAL JOINsürekli olarak sütunlar olarak adlandırılır, çünkü birleşimler aynı adlara sahip sütunlarda ima edilir (SQL'de sütunları yeniden adlandırmak için sözdiziminin ayrıntılı olması, ancak yan etki, temel tablolarda sütunları adlandırırken disiplini teşvik etmektir. VIEWs :)

SQL'in NATURAL JOINbir equi-join ** olduğunu unutmayın, ancak bu kullanışlılık için bir çubuk değildir. Eğer düşünün NATURAL JOINSQL desteklenen tek katılmak tip oldu hala olurdu ilişkisel tam .

Gerçekten de herhangi birinin projeksiyon ve projeksiyon ( ) NATURAL JOINkullanılarak yazılabileceği doğru olsa da, herhangi birinin product ( ) ve resttion ( ); ayrıca , ortak sütun adı olmayan tablolar arasındaki a ile aynı sonucu verecektir . Dolayısıyla, yalnızca ilişkiler olan sonuçlarla (ve neden hiç olmasın ?!) ilgileniyorsanız, ihtiyacınız olan tek birleştirme türü budur. Elbette, bir dil tasarım perspektifinden değer gibi kısayolların olduğu ve değerlerinin olduğu doğrudur , ancak hemen hemen her SQL sorgusunun sözdizimsel olarak farklı, ancak anlamsal olarak eşdeğer, 10 şekilde yazılabileceğini düşünün ve bu, SQL optimizasyonlarını çok zorlaştıran şeydir geliştirmek.INNER JOINSELECTINNER JOINCROSS JOINWHERENATURAL JOINCROSS JOINNATURAL JOININNER JOINCROSS JOIN

Anlamsal olarak eşdeğer olan bazı örnek sorgular ( alışılmış parça ve tedarikçi veritabanını kullanarak ):

SELECT *
  FROM S NATURAL JOIN SP;

-- Must disambiguate and 'project away' duplicate SNO attribute
SELECT S.SNO, SNAME, STATUS, CITY, PNO, QTY
  FROM S INNER JOIN SP 
          USING (SNO);                        

-- Alternative projection
SELECT S.*, PNO, QTY
  FROM S INNER JOIN SP 
          ON S.SNO = SP.SNO;

-- Same columns, different order == equivalent?!
SELECT SP.*, S.SNAME, S.STATUS, S.CITY
  FROM S INNER JOIN SP 
      ON S.SNO = SP.SNO;

-- 'Old school'
SELECT S.*, PNO, QTY
  FROM S, SP 
 WHERE S.SNO = SP.SNO;

** İlişkisel doğal birleşme bir ekvator değildir, bir projeksiyonudur. - philipxy


İlişkisel doğal birleşme bir ekvator değildir, birinin bir izdüşümüdür. SQL doğal birleştirme bir SQL equijoin (kopyalar mümkündür) - iç birleşim kullanarak tanımlanır.
philipxy

@philipxy: Teşekkürler, değişiklikler yaptım. Yanlış beyanlar ve yanlış anlaşılmalar için lütfen - bu veya yanıtlarımın herhangi birini - düzenlemek için çekinmeyin. Hala sizden öğreniyorum :)
gün9

9

Bir NATURALkatılmak bir sadece kısa sözdizimi özgü INNER ya da "eş-katıl" - - ve, sözdizimi açılmadığı zamanlar, her ikisi de aynı İlişkisel Cebir operasyonu temsil katılmak. Bu, OUTER( LEFT/ RIGHT) veya CROSSbirleşme durumlarında olduğu gibi "farklı bir tür birleşim" değildir .

Bkz eşit-katılmak Wikipedia'da bölümü:

Doğal bir birleşim, ek birleşimlerin daha fazla uzmanlaşmasını sağlar. Birleştirme yüklemi, her iki tabloda da birleştirilen tablolarda aynı sütun adlarına sahip tüm sütunları karşılaştırarak dolaylı olarak ortaya çıkar . Sonuçta elde edilen birleştirilmiş tablo, eşit olarak adlandırılmış her bir sütun çifti için yalnızca bir sütun içerir.

Çoğu uzman , NATURAL JOIN'lerin tehlikeli olduğunu kabul eder ve bu nedenle kullanımlarını kesinlikle caydırır. Tehlike yanlışlıkla başka bir sütunla aynı adlı yeni bir sütun eklemekten kaynaklanır ...

Yani, bütün NATURALolarak yazılabilir katılır INNERkatılır (ama tersi doğru değildir). Bunu yapmak için yüklemi açık bir şekilde oluşturun - ör. USINGVeya ON- ve Jonathan Leffler'in işaret ettiği gibi, istenirse "yinelemeleri" önlemek için istenen sonuç kümesi sütunlarını seçin.

Mutlu kodlama.


( NATURALAnahtar kelime de birleştirilebilir LEFTve RIGHTbirleştirilebilir ve aynı durum geçerlidir. Birleştirme , belirli bir birleştirme NATURAL LEFT/RIGHTiçin yalnızca kısa bir sözdizimidir .) LEFT/RIGHT


2
"NATURAL birleşimi [snip]" equi-join "için sadece kısa bir sözdizimidir - ve sözdizimi kaydırıldıktan sonra her ikisi de aynı İlişkisel Cebiri temsil eder" - haklısınız: ilişkisel cebir için doğrudur ama cevabınız bozulur ondan sonra, örneğin "Çoğu uzman DOĞAL BİRLEŞMELERİN tehlikeli olduğunu kabul eder ve bu nedenle kullanımlarını şiddetle caydırır" - ilişkisel cebirdeki uzmanlar bunu söylüyor ?!
oneday3

2

Doğal Birleştirme: İki tablodaki tüm sütunların birleşimidir. İlk tablodaki tüm satırları ikinci tabloya göre döndürecektir.

İç Birleştirme: Bu birleşim, sütun adlarından herhangi biri iki tabloda sxame olmazsa çalışır


3
Cevabınızın yeterince açık olduğunu düşünmüyorum ve düzeltmek için büyük bir yeniden yazma gerekiyordu.
gün

0

Doğal Birleştirme, tüm ortak sütunlar temelinde 2 tablonun birleştirildiği yerdir.

ortak sütun: her iki tabloda da aynı ada sahip bir sütundur + her iki tabloda da uyumlu veri türlerine sahiptir. Yalnızca = operatörünü kullanabilirsiniz

İç Birleştirme, ON yan tümcesinde belirtilen ortak sütunlar temelinde 2 tablonun birleştirildiği yerdir.

ortak sütun: her iki tabloda da uyumlu veri türlerine sahip olan ancak aynı ada sahip olması gerekmeyen bir sütundur. Sen gibi sadece herhangi karşılaştırma operatörünü kullanabilirsiniz =, <=, >=, <, >,<>


-2

fark iç (equi / default) birleşiminde ve natuarl birleşiminde ortak sütun kazanımının tek seferde görüntüleneceği, ancak iç / equi / default / basit birleşim ortak sütununda iki kez görüntülenecek olmasıdır.


-2

İç birleşim ve doğal birleşim neredeyse aynıdır, ancak aralarında küçük bir fark vardır. Fark doğal birleşimde koşul belirtmeye gerek yoktur, ancak iç birleşim durumunda zorunludur. İç birleşmede durumu belirtirsek, sonuçta ortaya çıkan tablolar kartezyen bir ürün gibidir.


Birleştirme koşullarını belirtmeye neden gerek yok? Hangi koşullar altında bir iç birleşimdeki koşulları belirtmek kartezyen bir ürün gibi bir şeyle sonuçlanır?
gün2

Dış ve iç birleşimi "neredeyse aynı" olarak adlandırmak hafif bir yetersizlik imho .. belki de değerlendirme üzerinde ayrıntılı olabilir?
TMOTTM

-3
mysql> SELECT  * FROM tb1 ;
+----+------+
| id | num  |
+----+------+
|  6 |   60 |
|  7 |   70 |
|  8 |   80 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

mysql> SELECT  * FROM tb2 ;
+----+------+
| id | num  |
+----+------+
|  4 |   40 |
|  5 |   50 |
|  9 |   90 |
|  1 |    1 |
|  2 |    2 |
|  3 |    3 |
+----+------+
6 rows in set (0.00 sec)

İÇ BİRLEŞİM :

mysql> SELECT  * FROM tb1 JOIN tb2 ; 
+----+------+----+------+
| id | num  | id | num  |
+----+------+----+------+
|  6 |   60 |  4 |   40 |
|  7 |   70 |  4 |   40 |
|  8 |   80 |  4 |   40 |
|  1 |    1 |  4 |   40 |
|  2 |    2 |  4 |   40 |
|  3 |    3 |  4 |   40 |
|  6 |   60 |  5 |   50 |
|  7 |   70 |  5 |   50 |
|  8 |   80 |  5 |   50 |
.......more......
return 36 rows in set (0.01 sec) 
AND NATURAL JOIN :

    mysql> SELECT  * FROM tb1 NATURAL JOIN tb2 ;
    +----+------+
    | id | num  |
    +----+------+
    |  1 |    1 |
    |  2 |    2 |
    |  3 |    3 |
    +----+------+
    3 rows in set (0.01 sec)

-4

İç birleşim, sütun adının aynı olduğu iki tabloya katılın.

Doğal birleştirme, sütun adı ve veri türlerinin aynı olduğu iki tabloyu birleştirin.


Bu tamamen yanlış. A NATURAL JOIN(birkaç kişinin yıllar önce işaret ettiği gibi) sütun adlarının aynı olduğu yerdir. Veri türünün aynı olması gerekmez. Bir INNER JOINihtiyaç için kullanılan alanların adı aynı değildir.
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.