SQL JOIN ve farklı JOIN türleri


244

SQL nedir JOINve farklı türler nelerdir?

Yanıtlar:


330

W3schools'tan bir örnek :


INNER JOIN - Yalnızca her iki tablodaki koşulla eşleşen kayıtlar


SOL BİRLEŞTİR - Tablo 2'deki koşulla eşleşen kayıtlarla birlikte tablo 1'deki tüm kayıtlar


RIGHT JOIN - Tablo 2'deki koşulla eşleşen kayıtlarla birlikte tablo 2'deki tüm kayıtlar


FULL OUTER JOIN - Sol ve Sağ Dış birleşimlerin ON deyimiyle eşleşen ancak her iki tablonun korunması



27
@KNU w3fools resimler için fikir aldıkları yerden kredi vermelidir. Bkz . SQL birleşimlerinin Jeff Atwood tarafından yazılması (evet, SO'yu birlikte yazan kişi) ve Ligaya Turmelle'nin Jeff fikrini aldığı ve yaydığı bağlantılı makalesi .
ypercubeᵀᴹ

2
@avi sol ve sağ birleşimleri benzerdir, eğer birleştirilmenin temel aldığı birincil tablo olan rahatsız olmazsanız.
Anup

2
@philipxy: Bu garip bir tanım (haklı olsanız bile). Ama tam tersine gitmeyi ve çapraz birleştirme ile başlamayı ve sonra üstüne "iç" birleştirmeyi tercih ederim. Sonuçta, sadece çapraz birleşme kavramı bu gayri resmi ve yanlış Venn diyagramı görselleştirmelerini geçersiz kılar ...
Lukas Eder

1
Bu resimler, birliğin tam dış birleşim ile aynı olduğunu ve kesişimin bildiğim kadar doğru olmayan iç birleşim ile aynı olduğunu ima ediyor gibi görünüyor.
mightyWOZ

1
@DevDave, çünkü popüler inanışın aksine - bir resim bin kelimeye bedel değildir. Bir sonraki cevaba bakınız.
hyankov

248

Nedir SQL JOIN?

SQL JOIN iki veya daha fazla veritabanı tablosundan veri alma yöntemidir.

Farklı olan nedir SQL JOIN?

Toplam beş JOINs var. Onlar :

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. KATIL veya İÇ KAT:

Bu tür bir JOINa'da, her iki tabloda da koşulla eşleşen tüm kayıtları alırız ve her iki tabloda da eşleşmeyen kayıtlar raporlanmaz.

Başka bir deyişle, INNER JOINtek gerçeğe dayanmaktadır: SADECE İKİ eşleşen girişler tablolar listelenmelidir.

Bir o Not JOINbaşka olmaksızın JOINanahtar kelimeler (gibi INNER, OUTER, LEFT, vs) bir olduğunu INNER JOIN. Başka bir deyişle, JOINsözdizimsel bir şekerdir INNER JOIN(bakınız: JOIN ve INNER JOIN arasındaki fark ).

2. DIŞ KATILIM:

OUTER JOIN verilerini geri çağırır

Ya bir tablodaki eşleşen satırlar ve diğer tablodaki tüm satırlar Ya da, tüm tablolardaki tüm satırlar (eşleşme olup olmadığı önemli değildir).

Üç çeşit Dış birleşim vardır:

2.1 SOL DIŞ ORTAK veya SOL KATIL

Bu birleştirme, sol tablodaki tüm satırları sağ tablodaki eşleşen satırlarla birlikte döndürür. Sağ tabloda eşleşen sütun yoksa, NULLdeğerleri döndürür .

2.2 DOĞRU DIŞ ORTAK veya SAĞ KATIL

Bu JOIN, sağ tablodaki tüm satırları, sol tablodaki eşleşen satırlarla birlikte döndürür. Sol tabloda eşleşen sütun yoksa, NULLdeğerleri döndürür .

2.3 TAM DIŞ ORTAK veya FULL KATILIM

Bu JOINbirleştirir LEFT OUTER JOINve RIGHT OUTER JOIN. Koşullar karşılandığında her iki tablodan satır döndürür ve NULLeşleşme olmadığında değer döndürür .

Başka bir deyişle, OUTER JOINSADECE tablolardan BİRİNDE (SAĞ veya SOL) veya tabloların HER İKİ (TAM) eşleşen girişler listelenmelidir.

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. DOĞAL KATILIM:

İki koşula dayanmaktadır:

  1. JOINeşitlik aynı adla tüm sütunlar üzerinde yapılır.
  2. Yinelenen sütunları sonuçtan kaldırır.

Bu, doğası gereği daha teorik görünmektedir ve sonuç olarak (muhtemelen) çoğu DBMS bunu desteklemekten bile rahatsız değildir.

4. ÇAPRAZ KATIL:

İlgili iki tablonun Kartezyen ürünüdür. Bir CROSS JOINdurumun sonucu çoğu durumda mantıklı değildir. Dahası, buna hiç ihtiyacımız olmayacak (ya da en azından kesin olmak gerekirse).

5. KENDİNE KATIL:

Bu farklı bir formu değil JOINdaha ziyade olduğu, JOIN( INNER, OUTERkendisi için bir tablonun, vb).

Operatörlere Dayalı JOIN'ler

Bir JOINcümle için kullanılan operatöre bağlı olarak, iki tür JOINs olabilir. Onlar

  1. Equi KATIL
  2. Teta KATIL

1. Equi KATIL:

Ne JOINtür olursa olsun ( INNER, OUTERvb.) SADECE eşitlik operatörünü (=) kullanırsak, JOINbunun bir EQUI JOIN.

2. Theta KATILIN:

Bu aynıdır EQUI JOINancak>, <,> = vb. Gibi diğer tüm işleçlere izin verir.

Birçok ikisini de göz önüne EQUI JOINve Teta JOINbenzer INNER, OUTER vs JOINler. Ama bunun bir hata olduğuna ve fikirleri belirsizleştirdiğine inanıyorum. Çünkü INNER JOIN, OUTER JOINvb. Tüm tablolar ve onların verileri ile bağlantılıdır EQUI JOINve THETA JOINsadece eskisinde kullandığımız operatörlerle bağlantılıdır.

Yine, bir NATURAL JOINtür "tuhaf" olarak kabul eden birçok kişi var EQUI JOIN. Aslında, bahsettiğim ilk koşul nedeniyle doğrudur NATURAL JOIN. Ancak, bunu sadece NATURAL JOINyalnızlıkla sınırlamak zorunda değiliz . INNER JOINs, OUTER JOINs vs de olabilir EQUI JOIN.


2
Nispeten yeni LATERAL JOIN var .. SELECT * r1, LATERAL fx (r1)
Pavel Stehule

13
Bu makul görünse de, yararlı bilgiler taşıyan herhangi bir şekilde "SQL birleşimi nedir" diye cevap vermediğini düşünmüyorum. Bir bütün olarak cevap, bu soruları soran türden insanlar için değil, birleşimleri zaten anlayan insanlar için yazılmış bir referanstır. Ayrıca, hem iddialarını desteklemek (hem de yetkili bir cevap verirken uygun olduğu gibi) hem de dış kaynaklar yoluyla ek açıklama sağlamak için referansları atlar. Yeni SQL kullanıcılarını bağlamak için yetkili bir yanıt yazmaya çalışıyorsanız, boşlukları biraz doldurmaya değebilir, özellikle "birleştirme nedir" bölümü.
Craig Ringer

bazı örnekler verebilir misiniz?
avi

67

Tanım:


JOINS, aynı anda birden çok tablodan birleştirilen verileri sorgulamanın yoludur.

KATILIM Türleri:


RDBMS ile ilgili olarak 5 tip birleştirme vardır:

  • Equi-Join: Eşitlik durumuna göre iki tablodaki ortak kayıtları birleştirir. Teknik olarak, Bir tablonun Birincil Anahtarının değerlerini ve başka bir tablonun Yabancı Anahtar değerlerini karşılaştırmak için eşitlik operatörü (=) kullanılarak yapılan Join, dolayısıyla sonuç kümesi her iki tabloda da ortak (eşleşen) kayıtları içerir. Uygulama için INNER-JOIN'e bakınız.

  • Natural-Join: SELECT işleminin yinelenen sütunu atladığı Equi-Join'ın geliştirilmiş sürümüdür. Uygulama için bkz. INNER-JOIN

  • Equi-Join olmayan: Birleştirme koşulunun eşit işleç (=) dışında kullanıldığı durumlarda Equi-join tersidir; örneğin,! =, <=,> =,>, <Veya BETWEEN vb. Uygulama için INNER-JOIN'e bakınız.

  • Kendi Kendine Katılma: Bir tablonun kendisiyle birleştiği özelleştirilmiş birleştirme davranışı; Bu genellikle kendi kendine referans veren tabloları (veya Tekli ilişki varlığını) sorgulamak için gereklidir. Uygulama için INNER-JOIN'lere bakınız.

  • Kartezyen Ürün: Çapraz, her iki tablonun tüm kayıtlarını herhangi bir koşul olmaksızın birleştirir. Teknik olarak, WHERE-Clause içermeyen bir sorgunun sonuç kümesini döndürür.

SQL endişesine ve ilerlemesine göre, 3 tür bağlantı vardır ve tüm RDBMS birleştirmeleri bu tür birleştirmeler kullanılarak gerçekleştirilebilir.

  1. INNER-JOIN: Eşleşen satırları iki tablodan birleştirir (veya birleştirir). Eşleştirme, tabloların ortak sütunlarına ve karşılaştırma işlemlerine göre yapılır. Eşitlik temelli koşul varsa: EQUI-JOIN gerçekleştirildi, aksi takdirde EQUI-Join değil.

  2. OUTER-JOIN: Eşleşen satırları iki tablodan ve eşleşmeyen satırları NULL değerleriyle birleştirir (veya birleştirir). Bununla birlikte, eşleşmemiş satırların seçimini özelleştirebilir, örneğin, alt tablolara göre ilk tablodan veya ikinci tablodan eşleşmeyen satırı seçme: SOL DIŞ BİRLEŞTİR ve SAĞ DIŞ BİRLEŞTİR.

    2.1. LEFT Outer JOIN (diğer adıyla LEFT-JOIN): İki tablodan eşleşen satırları döndürür ve yalnızca LEFT tablosundan (yani ilk tablo) eşleşmez.

    2.2. RIGHT Outer JOIN (diğer bir deyişle RIGHT-JOIN): İki tablodan eşleşen satırları döndürür ve yalnızca RIGHT tablosundan eşleşmez.

    2.3. FULL OUTER JOIN (diğer adıyla OUTER JOIN): Her iki tabloda da eşleşen ve eşleşmeyen döndürür.

  3. ÇAPRAZ BAĞLANTI: Bu birleştirme Kartezyen ürünü yerine birleştirmez / birleştirmez.

resim açıklamasını buraya girin Not: Self-JOIN, gereksinime göre INNER-JOIN, OUTER-JOIN ve CROSS-JOIN ile elde edilebilir, ancak tablo kendisiyle birleşmelidir.

Daha fazla bilgi için:

Örnekler:

1.1: INNER-JOIN: Eşit katılma uygulaması

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;

1.2: INNER-JOIN: Doğal-JOIN uygulaması

Select A.*, B.Col1, B.Col2          --But no B.ForeignKeyColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3: NON-Equi-join uygulamasıyla INNER-JOIN

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4: KENDİ KENDİNE KATILIN

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

2.1: DIŞ BİRLEŞTİR (tam dış birleşim)

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

2.2: SOL GİRİŞ

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

2.3: DOĞRU KATILIM

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1: ÇAPRAZ KATIL

Select *
 FROM TableA CROSS JOIN TableB;

3.2: ÇAPRAZ KATIL - Kendine KATIL

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

//VEYA//

Select *
 FROM Table1 A1,Table1 A2;

"Tablo 1" ve "Tablo 2" etiketleri ve altındaki etiketler uygunsuz, intersect/ except/ union; burada daireler , numaralı etiketlerin dediği gibi left& ile döndürülen satırlardır right join. AXB resmi saçmalıktır. cross join= inner join on 1=1& ilk diyagramın özel bir halidir.
philipxy

Bahsetmeye değer SQL-92 tanımlar UNION JOIN. SQL: 2003 artık kullanılmıyor.
Impaler

40

İlginçtir ki diğer cevapların çoğu bu iki problemden muzdariptir:

Son zamanlarda konuyla ilgili bir makale yazdım: Muhtemelen Eksik, Kapsamlı Bir Tablo, SQL'de Tablolara KATILMAK için Birçok Farklı Yolda , burada özetleyeceğim.

İlk ve en önemlisi: JOIN'ler kartezyen ürünlerdir

Bu yüzden Venn diyagramları onları yanlış bir şekilde açıklıyor, çünkü bir JOIN birleştirilen iki tablo arasında kartezyen bir ürün yaratıyor . Wikipedia bunu güzel bir şekilde gösteriyor:

resim açıklamasını buraya girin

Kartezyen ürünler için SQL sözdizimi CROSS JOIN. Örneğin:

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

Bu, bir tablodaki tüm satırları diğer tablodaki tüm satırlarla birleştirir:

Kaynak:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+

Sonuç:

+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+

Virgülle ayrılmış tablolar listesi yazarsak, aynısını alırız:

-- CROSS JOINing two tables:
SELECT * FROM table1, table2

İÇ KATILIM (Theta-JOIN)

An INNER JOINsadece ilişkisel cebirde CROSS JOINfiltre yükleminin çağrıldığı bir filtredir Theta.

Örneğin:

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

Anahtar kelimenin INNERisteğe bağlı olduğunu unutmayın (MS Access hariç).

( sonuç örnekleri için makaleye bakın )

EQUI KATILDI

Özel bir tür Theta-JOIN, en çok kullandığımız equi JOIN'dir. Yüklem, bir tablonun birincil anahtarını başka bir tablonun yabancı anahtarıyla birleştirir. Sakila veritabanını gösterim amacıyla kullanırsak şunu yazabiliriz:

SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id

Bu, tüm aktörleri filmleriyle birleştirir.

Veya bazı veritabanlarında:

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

USING()Sözdizimi operasyonun tabloları JOIN ve bu iki sütun üzerinde eşitlik yüklemi yaratır her iki tarafında bulunması gereken bir sütun belirtmek için izin verir.

DOĞAL KATILIM

Diğer yanıtlar bu "JOIN tipini" ayrı olarak listeledi, ancak bu mantıklı değil. Sadece Theta-JOIN veya INNER JOIN'in özel bir örneği olan equi JOIN için bir sözdizimi şeker formudur. NATURAL JOIN , birleştirilen her iki tablo için ortak olan tüm sütunları toplar ve USING()bu sütunları birleştirir . Kazara eşleşmelerden ( Sakila veritabanındakiLAST_UPDATE sütunlar gibi) dolayı neredeyse hiç yararlı değildir .

İşte sözdizimi:

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

DIŞ KATILIM

Şimdi, birkaç kartezyen üründen bir tane oluşturduğundan OUTER JOINbiraz farklıdır . Yazabiliriz:INNER JOINUNION

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

Kimse ikincisini yazmak istemez, bu yüzden yazıyoruz OUTER JOIN(genellikle veritabanları tarafından daha iyi optimize edilir).

Gibi INNER, anahtar kelime OUTERburada, isteğe bağlıdır.

OUTER JOIN üç çeşittir:

  • LEFT [ OUTER ] JOIN: JOINİfadenin sol tablosu yukarıda gösterildiği gibi birleşime eklenir.
  • RIGHT [ OUTER ] JOIN: JOINİfadenin sağ tablosu yukarıda gösterildiği gibi birleşime eklenir.
  • FULL [ OUTER ] JOIN: JOINİfadenin her iki tablosu da yukarıda gösterildiği gibi birleşmeye eklenir.

Tüm bunlar anahtar kelimeyle USING()veya ile birleştirilebilir NATURAL( Aslında NATURAL FULL JOINson zamanlarda gerçek bir dünya kullanım durumum vardı )

Alternatif sözdizimleri

Oracle ve SQL Server'da, OUTER JOINSQL standardının bunun için bir sözdizimine sahip olmadan önce desteklenen bazı tarihi, kullanımdan kaldırılmış sözdizimleri vardır :

-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id

Bunu söyledikten sonra, bu sözdizimini kullanmayın. Bunu burada listeliyorum, böylece eski blog yayınlarından / eski kodlardan tanıyabilirsiniz.

Kisimlandirilmis OUTER JOIN

Birkaç kişi bunu biliyor, ancak SQL standardı bölümlenmiş OUTER JOIN(ve Oracle bunu uygular) belirtir . Bunun gibi şeyler yazabilirsiniz:

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

Sonucun bölümleri:

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

Buradaki nokta, birleştirme işleminin bölümlenmiş tarafındaki tüm satırların JOIN"JOIN'in diğer tarafında" eşleşen bir şey olursa olsun sonuçta sona erecek olmasıdır . Uzun lafın kısası: Bu, raporlardaki seyrek verileri doldurmak içindir. Çok kullanışlı!

YARI KATILIM

Ciddi anlamda? Başka cevap yok mu? Elbette hayır, çünkü SQL'de yerel bir sözdizimi yok, maalesef (aşağıdaki ANTI JOIN gibi). Ancak , örneğin filmlerde oynamış tüm aktörleri bulmak için IN()ve kullanabiliriz EXISTS():

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

WHERE a.actor_id = fa.actor_idYarı öncül katılmak gibi yüklem hareket eder. Buna inanmıyorsanız, yürütme planlarına bakın, örneğin Oracle. Veritabanının EXISTS()yüklemi değil, bir SEMI JOIN işlemini yürüttüğünü göreceksiniz .

resim açıklamasını buraya girin

ANTI JOIN

Bu yarı tam tersidir JOIN ( kullanmamaya dikkat NOT INrağmen , önemli bir ihtar vardır gibi)

İşte filmsiz tüm aktörler:

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

Bazı kişiler (özellikle MySQL kullanıcıları) ayrıca ANTI JOIN yazarlar:

SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL

Bence tarihi sebep performans.

LATERAL KATILIM

Aman Tanrım, bu çok havalı. Bundan bahseden tek kişi ben miyim? İşte harika bir sorgu:

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true

Oyuncu başına TOP 5 gelir getiren filmler bulacak. Her şey için bir TOP-N sorgusuna ihtiyacınız LATERAL JOINolduğunda, arkadaşınız olacaktır. SQL Server kullanıcısıysanız JOIN, adın altında bu türü biliyorsunuzAPPLY

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

Tamam, belki de bu hile, çünkü a LATERAL JOINveya APPLYifade gerçekten birkaç satır üreten bir "ilişkili alt sorgu" dur. Ancak "ilişkili alt sorgulara" izin verirsek, aynı zamanda ...

MULTISET

Bu yalnızca Oracle ve Informix tarafından (bildiklerime göre) uygulanır, ancak diziler ve / veya XML kullanılarak PostgreSQL'de ve XML kullanarak SQL Server'da taklit edilebilir.

MULTISETilişkili bir alt sorgu üretir ve ortaya çıkan satır kümesini dış sorguya yerleştirir. Aşağıdaki sorgu tüm aktörleri seçer ve her aktör için filmlerini iç içe bir koleksiyonda toplar:

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor

Görüldüğü gibi, orada sadece "sıkıcı" den JOIN daha türleridir INNER, OUTERve CROSS JOINgenellikle bahsedilmektedir. Makalemde daha fazla ayrıntı var . Ve lütfen, onları göstermek için Venn diyagramlarını kullanmayı bırakın.


Equijoin, teta eşitliğinin olduğu teta-birleşiminin özel durumudur. Teta birleşimi, her birinin bir sütunun onta karşılaştırması olduğu özel bir iç birleşim örneğine benzer. Codd'un onları tanımlamasından birkaç on yıl sonra, bazı ders kitapları, teta birleştirmesini iç birleştirmenin analogu olan bir genelleme olarak yanlış tanımladı.
philipxy

@philipxy: Cevabımda değişmesi gereken özel bir şey var mı? Bir düzenleme önerebilirsiniz ...
Lukas Eder

10

Bence kelimelerden daha iyi açıklayan bir örnek oluşturdum: SQL Join açıklama tablosu


@Niraj A ve B çevrelerinde A ve B satırları bulunmaz. Başka bir yerden körü körüne kredi olmadan kopyalanırlar. Çapraz birleşim iç birleşim çantasına dahildir, iç birleşim 1 = 1'dir. Resmin bu kısımları ne şekilde "mükemmel"?
philipxy

@philipxy Üzgünüm ama başka bir yerden kopyalandığından rahatsız değilim. ve yukarıdaki resimde hangisinin doğru olmadığından emin değilim. benim için sorun değil. Çapraz birleşim burada açıklanmamıştır. Bir iç birleşime dahil değildir ..
Niraj

-3

Ben evcil hayvan peeve itmek: USING anahtar kelime.

JOIN'in her iki tarafında da her iki tablonun yabancı anahtarları düzgün bir şekilde adlandırılmışsa (yani, sadece "id değil, aynı ad), bu kullanılabilir:

SELECT ...
FROM customers JOIN orders USING (customer_id)

Bunu çok pratik, okunabilir ve yeterince sık kullanmıyorum.


2
Bu soruya cevap vermiyor. Soru altında ya da cevaplardan birinde bir yorum olarak yer alır.
TylerH
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.