SQL JOIN und verschiedene Arten von JOINs


244

Was ist ein SQL JOINund was sind verschiedene Typen?

Antworten:


330

Eine Illustration von W3schools :


INNER JOIN - Nur Datensätze, die der Bedingung in beiden Tabellen entsprechen


LEFT JOIN - Alle Datensätze aus Tabelle 1 in Verbindung mit Datensätzen, die der Bedingung in Tabelle 2 entsprechen


RIGHT JOIN - Alle Datensätze aus Tabelle 2 in Verbindung mit Datensätzen aus Tabelle 1, die der Bedingung entsprechen


FULL OUTER JOIN - Die Kombination von Left und Right Outer verbindet die übereinstimmende ON-Klausel, behält jedoch beide Tabellen bei



27
@KNU Die w3fools sollten angeben, woher sie die Idee für die Bilder haben. Siehe Eine Visualisierung von SQL-Joins von Jeff Atwood (ja, derjenige, der SO mitverfasst hat) und den verlinkten Artikel von Ligaya Turmelle, in dem Jeff die Idee hatte und sie erweiterte.
Ypercubeᵀᴹ

2
@avi linke und rechte Verknüpfungen sind ähnlich, wenn Sie sich nicht darum kümmern, auf welcher Primärtabelle die Verknüpfung basiert.
Anup

2
@philipxy: Das ist eine seltsame Definition (auch wenn Sie richtig sind). Aber ich gehe lieber in die andere Richtung und beginne mit Cross Join und "baue" dann einen inneren Join darüber. Immerhin macht das bloße Konzept der Kreuzverknüpfung diese informellen und ungenauen Venn-Diagrammvisualisierungen ungültig ...
Lukas Eder

1
Diese Bilder scheinen zu implizieren, dass die Vereinigung mit der vollständigen äußeren Verbindung identisch ist und die Schnittmenge mit der inneren Verbindung identisch ist, was meines Wissens nicht korrekt ist.
mächtige WOZ

1
@ DevDave, denn entgegen der landläufigen Meinung sagt ein Bild nicht mehr als tausend Worte. Siehe nächste Antwort.
Hyankov

248

Was ist SQL JOIN?

SQL JOIN ist eine Methode zum Abrufen von Daten aus zwei oder mehr Datenbanktabellen.

Was sind die verschiedenen SQL JOINs?

Es gibt insgesamt fünf JOINs. Sie sind :

  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. JOIN oder INNER JOIN:

In dieser Art von a erhalten JOINwir alle Datensätze, die der Bedingung in beiden Tabellen entsprechen, und Datensätze in beiden Tabellen, die nicht übereinstimmen, werden nicht gemeldet.

Mit anderen Worten, INNER JOINbasiert auf der einzigen Tatsache, dass: NUR die übereinstimmenden Einträge in BEIDEN der Tabellen aufgelistet werden sollten.

Beachten Sie, dass eine JOINohne andere JOINSchlüsselwörter (wie INNER, OUTER, LEFTusw.) ein ist INNER JOIN. Mit anderen Worten, JOINist ein syntaktischer Zucker für INNER JOIN(siehe: Unterschied zwischen JOIN und INNER JOIN ).

2. OUTER JOIN:

OUTER JOIN ruft ab

Entweder die übereinstimmenden Zeilen aus einer Tabelle und alle Zeilen in der anderen Tabelle oder alle Zeilen in allen Tabellen (es spielt keine Rolle, ob eine Übereinstimmung vorliegt oder nicht).

Es gibt drei Arten von Outer Join:

2.1 LEFT OUTER JOIN oder LEFT JOIN

Dieser Join gibt alle Zeilen aus der linken Tabelle in Verbindung mit den übereinstimmenden Zeilen aus der rechten Tabelle zurück. Wenn in der rechten Tabelle keine übereinstimmenden Spalten vorhanden sind, werden NULLWerte zurückgegeben.

2.2 RECHTE AUSSENVERBINDUNG oder RECHTE VERBINDUNG

Dies JOINgibt alle Zeilen aus der rechten Tabelle in Verbindung mit den übereinstimmenden Zeilen aus der linken Tabelle zurück. Wenn in der linken Tabelle keine übereinstimmenden Spalten vorhanden sind, werden NULLWerte zurückgegeben.

2.3 FULL OUTER JOIN oder FULL JOIN

Dies JOINkombiniert LEFT OUTER JOINund RIGHT OUTER JOIN. Es gibt Zeilen aus beiden Tabellen zurück, wenn die Bedingungen erfüllt sind, und gibt den NULLWert zurück, wenn keine Übereinstimmung vorliegt .

Mit anderen Worten, OUTER JOINbasiert auf der Tatsache, dass: NUR die übereinstimmenden Einträge in EINER DER Tabellen (RECHTS oder LINKS) oder BEIDEN der Tabellen (VOLL) aufgelistet werden SOLLTEN.

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

3. NATÜRLICHE VERBINDUNG:

Es basiert auf den beiden Bedingungen:

  1. Das JOINwird für alle gleichnamigen Spalten aus Gründen der Gleichheit erstellt.
  2. Entfernt doppelte Spalten aus dem Ergebnis.

Dies scheint eher theoretischer Natur zu sein, und aus diesem Grund unterstützen (wahrscheinlich) die meisten DBMS dies nicht einmal.

4. CROSS JOIN:

Es ist das kartesische Produkt der beiden beteiligten Tabellen. Das Ergebnis von a CROSS JOINwird in den meisten Situationen keinen Sinn ergeben. Darüber hinaus brauchen wir das überhaupt nicht (oder am wenigsten, um genau zu sein).

5. SELBSTVERBINDUNG:

Es ist nicht eine andere Form JOIN, sondern es ist ein JOIN( INNER, OUTERusw.) eine Tabelle mit mir selbst.

JOINs basierend auf Operatoren

Abhängig vom Operator, der für eine JOINKlausel verwendet wird, kann es zwei Arten von JOINs geben. Sie sind

  1. Equi JOIN
  2. Theta BEITRETEN

1. Equi JOIN:

Aus welchem JOINTyp ( INNER, OUTERusw.), wenn wir nur den Gleichheitsoperator (=) verwenden, dann sagen wir , dass das JOINeine ist EQUI JOIN.

2. Theta JOIN:

Dies ist dasselbe wie EQUI JOIN, erlaubt jedoch alle anderen Operatoren wie>, <,> = usw.

Viele betrachten beide EQUI JOINund Theta JOINähnlich wie INNER, OUTER usw. JOINs. Aber ich glaube fest daran, dass es ein Fehler ist und die Ideen vage macht. Denn INNER JOIN, OUTER JOINetc sind alle mit den Tabellen und ihren Daten verbunden , während EQUI JOINund THETA JOINsind nur mit den Betreibern wir in der ehemaligen verwenden verbunden.

Wieder gibt es viele, die NATURAL JOINals eine Art "eigenartig" betrachten EQUI JOIN. In der Tat ist es wahr, wegen der ersten Bedingung, für die ich erwähnt habe NATURAL JOIN. Wir müssen das jedoch nicht einfach auf NATURAL JOINs allein beschränken. INNER JOINs, OUTER JOINs etc könnte auch ein EQUI JOINsein.


2
Es gibt relativ neue LATERAL JOIN .. SELECT * FROM r1, LATERAL fx (r1)
Pavel Stehule

13
Obwohl dies vernünftig erscheint, denke ich nicht, dass Antworten "Was ist ein SQL-Join?" In irgendeiner Weise nützliche Informationen vermitteln. Die Antwort als Ganzes ist eine Referenz für Leute, die Joins bereits verstehen, nicht für die Art von Leuten, die diese Fragen stellen. Es werden auch Verweise weggelassen, um sowohl seine Behauptungen zu stützen (wie es angemessen ist, wenn eine autorisierende Antwort gegeben wird) als auch um zusätzliche Erklärungen über externe Ressourcen bereitzustellen. Wenn Sie versuchen, eine autorisierende Antwort zu schreiben, mit der neue SQL-Benutzer verknüpft werden sollen, sollten Sie die Lücken ein wenig ausfüllen, insbesondere den Teil "Was ist ein Join?".
Craig Ringer

Können Sie einige Beispiele nennen?
Avi

67

Definition:


Mit JOINS können Sie die Daten abfragen, die aus mehreren Tabellen gleichzeitig kombiniert wurden.

Arten von JOINS:


In Bezug auf RDBMS gibt es 5 Arten von Verknüpfungen:

  • Equi-Join: Kombiniert gemeinsame Datensätze aus zwei Tabellen basierend auf der Gleichheitsbedingung. Technisch gesehen wird Join mithilfe des Gleichheitsoperators (=) erstellt, um die Werte des Primärschlüssels einer Tabelle und der Fremdschlüsselwerte einer anderen Tabelle zu vergleichen. Daher enthält die Ergebnismenge gemeinsame (übereinstimmende) Datensätze aus beiden Tabellen. Zur Implementierung siehe INNER-JOIN.

  • Natural-Join: Es handelt sich um eine erweiterte Version von Equi-Join, bei der bei der SELECT-Operation doppelte Spalten weggelassen werden. Zur Implementierung siehe INNER-JOIN

  • Non-Equi-Join: Dies ist die Umkehrung des Equi-Joins, bei dem eine andere Join -Bedingung als der gleiche Operator (=) verwendet wird, z. B.! =, <=,> =,>, <Oder ZWISCHEN usw. Zur Implementierung siehe INNER-JOIN.

  • Self-Join :: Ein benutzerdefiniertes Join- Verhalten, bei dem eine Tabelle mit sich selbst kombiniert wird. Dies wird normalerweise zum Abfragen von selbstreferenzierenden Tabellen (oder einer unären Beziehungsentität) benötigt. Zur Implementierung siehe INNER-JOINs.

  • Kartesisches Produkt: Es kombiniert alle Datensätze beider Tabellen ohne Bedingung. Technisch gibt es die Ergebnismenge einer Abfrage ohne WHERE-Klausel zurück.

Gemäß SQL-Bedenken und -Erweiterungen gibt es drei Arten von Verknüpfungen, und alle RDBMS-Verknüpfungen können mit diesen Verknüpfungstypen erreicht werden.

  1. INNER-JOIN: Es werden übereinstimmende Zeilen aus zwei Tabellen zusammengeführt (oder kombiniert). Der Abgleich erfolgt anhand allgemeiner Tabellenspalten und ihrer Vergleichsoperation. Wenn eine auf Gleichheit basierende Bedingung, dann: EQUI-JOIN ausgeführt, andernfalls Non-EQUI-Join.

  2. OUTER-JOIN: Es werden übereinstimmende Zeilen aus zwei Tabellen und nicht übereinstimmende Zeilen mit NULL-Werten zusammengeführt (oder kombiniert). Es kann jedoch eine benutzerdefinierte Auswahl nicht übereinstimmender Zeilen vorgenommen werden, z. B. die Auswahl nicht übereinstimmender Zeilen aus der ersten Tabelle oder der zweiten Tabelle nach Untertypen: LEFT OUTER JOIN und RIGHT OUTER JOIN.

    2.1. LEFT Outer JOIN (auch bekannt als LEFT-JOIN): Gibt übereinstimmende Zeilen aus zwei Tabellen zurück, die nicht aus der LEFT-Tabelle (dh der ersten Tabelle) übereinstimmen.

    2.2. RIGHT Outer JOIN (auch bekannt als RIGHT-JOIN): Gibt übereinstimmende Zeilen aus zwei Tabellen zurück, die nur aus der RIGHT-Tabelle nicht übereinstimmen.

    2.3. FULL OUTER JOIN (auch bekannt als OUTER JOIN): Gibt übereinstimmende und nicht übereinstimmende Daten aus beiden Tabellen zurück.

  3. CROSS-JOIN: Dieser Join wird nicht zusammengeführt / kombiniert, sondern führt ein kartesisches Produkt aus.

Geben Sie hier die Bildbeschreibung ein Hinweis: Self-JOIN kann je nach Anforderung entweder durch INNER-JOIN, OUTER-JOIN und CROSS-JOIN erreicht werden, die Tabelle muss sich jedoch mit sich selbst verbinden.

Für mehr Informationen:

Beispiele:

1.1: INNER-JOIN: Equi-Join-Implementierung

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

1.2: INNER-JOIN: Natural-JOIN-Implementierung

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: INNER-JOIN mit NON-Equi-Join-Implementierung

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

1.4: INNER-JOIN mit SELF-JOIN

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

2.1: OUTER JOIN (vollständiger äußerer Join)

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

2.2: LINKS VERBINDEN

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

2.3: RECHTS BEITRETEN

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

3.1: CROSS JOIN

Select *
 FROM TableA CROSS JOIN TableB;

3.2: CROSS JOIN-Self JOIN

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

//ODER//

Select *
 FROM Table1 A1,Table1 A2;

Beschriftungen "Tabelle 1" & "Tabelle 2" & die Beschriftungen darunter sind unangemessen, sie stammen aus Abbildungen von intersect/ except/ union; Hier sind die Kreise die Zeilen, die von left& zurückgegeben werden right join, wie die nummerierten Bezeichnungen sagen. Das AXB-Bild ist Unsinn. cross join= inner join on 1=1& ist ein Sonderfall des ersten Diagramms.
Philipip

Es ist erwähnenswert, dass SQL-92 das definiert UNION JOIN. Jetzt veraltet in SQL: 2003.
Der Impaler

40

Interessanterweise leiden die meisten anderen Antworten unter diesen beiden Problemen:

Ich habe kürzlich einen Artikel zum Thema geschrieben: Eine wahrscheinlich unvollständige, umfassende Anleitung zu den vielen verschiedenen Möglichkeiten, Tabellen in SQL zu verbinden , die ich hier zusammenfassen werde.

In erster Linie: JOINs sind kartesische Produkte

Aus diesem Grund erklären Venn-Diagramme sie so ungenau, weil ein JOIN ein kartesisches Produkt zwischen den beiden verbundenen Tabellen erstellt. Wikipedia illustriert es gut:

Geben Sie hier die Bildbeschreibung ein

Die SQL-Syntax für kartesische Produkte lautet CROSS JOIN. Beispielsweise:

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

Welches kombiniert alle Zeilen aus einer Tabelle mit allen Zeilen aus der anderen Tabelle:

Quelle:

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

Ergebnis:

+--------+------------+
| 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     |
+--------+------------+

Wenn wir nur eine durch Kommas getrennte Liste von Tabellen schreiben, erhalten wir dasselbe:

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

INNER JOIN (Theta-JOIN)

An INNER JOINist nur ein CROSS JOINFilter, bei dem das Filterprädikat Thetain der relationalen Algebra aufgerufen wird .

Zum Beispiel:

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

Beachten Sie, dass das Schlüsselwort INNERoptional ist (außer in MS Access).

( Beispiele für Ergebnisse finden Sie im Artikel. )

EQUI JOIN

Eine besondere Art von Theta-JOIN ist Equi JOIN, das wir am häufigsten verwenden. Das Prädikat verknüpft den Primärschlüssel einer Tabelle mit dem Fremdschlüssel einer anderen Tabelle. Wenn wir die Sakila-Datenbank zur Veranschaulichung verwenden, können wir schreiben:

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

Dies kombiniert alle Schauspieler mit ihren Filmen.

Oder auch in einigen Datenbanken:

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

Die USING()Syntax ermöglicht die Angabe einer Spalte, die auf beiden Seiten der Tabellen einer JOIN-Operation vorhanden sein muss, und erstellt ein Gleichheitsprädikat für diese beiden Spalten.

NATÜRLICHE VERBINDUNG

Andere Antworten haben diesen "JOIN-Typ" separat aufgeführt, aber das macht keinen Sinn. Es ist nur eine Syntaxzuckerform für equi JOIN, was ein Sonderfall von Theta-JOIN oder INNER JOIN ist. NATURAL JOIN sammelt einfach alle Spalten, die beiden Tabellen gemeinsam sind, und verbindet USING()diese Spalten. Was aufgrund versehentlicher Übereinstimmungen (wie LAST_UPDATESpalten in der Sakila-Datenbank ) kaum nützlich ist .

Hier ist die Syntax:

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

OUTER JOIN

Jetzt OUTER JOINist ein bisschen anders, INNER JOINals es eines UNIONvon mehreren kartesischen Produkten schafft . Wir können schreiben:

-- 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>
)

Letzteres möchte niemand schreiben, also schreiben wir OUTER JOIN(was normalerweise durch Datenbanken besser optimiert wird).

Wie INNER, das Schlüsselwort OUTERist hier optional.

OUTER JOIN gibt es in drei Geschmacksrichtungen:

  • LEFT [ OUTER ] JOIN: Die linke Tabelle des JOINAusdrucks wird wie oben gezeigt zur Vereinigung hinzugefügt.
  • RIGHT [ OUTER ] JOIN: Die rechte Tabelle des JOINAusdrucks wird wie oben gezeigt zur Vereinigung hinzugefügt.
  • FULL [ OUTER ] JOIN: Beide Tabellen des JOINAusdrucks werden wie oben gezeigt zur Vereinigung hinzugefügt.

All dies kann mit dem Schlüsselwort USING()oder mit kombiniert werden NATURAL( ich hatte NATURAL FULL JOINkürzlich tatsächlich einen realen Anwendungsfall ).

Alternative Syntaxen

Es gibt einige historische, veraltete Syntaxen in Oracle und SQL Server, die OUTER JOINbereits unterstützt wurden, bevor der SQL-Standard eine Syntax dafür hatte:

-- 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

Verwenden Sie diese Syntax jedoch nicht. Ich liste dies hier nur auf, damit Sie es an alten Blog-Posts / Legacy-Code erkennen können.

Partitioniert OUTER JOIN

Nur wenige Leute wissen das, aber der SQL-Standard spezifiziert partitioniert OUTER JOIN(und Oracle implementiert es). Sie können solche Dinge schreiben:

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

Teile des Ergebnisses:

+--------+------------+------------+
| 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

Der Punkt hier ist, dass alle Zeilen von der partitionierten Seite des Joins im Ergebnis landen, unabhängig davon, ob das JOINauf der "anderen Seite des JOIN" übereinstimmt. Lange Rede, kurzer Sinn: Hiermit werden spärliche Daten in Berichten aufgefüllt. Sehr hilfreich!

SEMI JOIN

Ernsthaft? Keine andere Antwort hat das? Natürlich nicht, da es in SQL leider keine native Syntax gibt (genau wie ANTI JOIN unten). Aber wir können IN()und EXISTS()zB alle Schauspieler finden, die in Filmen gespielt haben:

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

Das WHERE a.actor_id = fa.actor_idPrädikat fungiert als Semi-Join-Prädikat. Wenn Sie es nicht glauben, lesen Sie die Ausführungspläne, z. B. in Oracle. Sie werden sehen, dass die Datenbank eine SEMI JOIN-Operation ausführt, nicht das EXISTS()Prädikat.

Geben Sie hier die Bildbeschreibung ein

ANTI JOIN

Dies ist genau das Gegenteil von SEMI JOIN ( darauf achten, nicht zu verwenden , NOT INobwohl , da es eine wichtige Einschränkung)

Hier sind alle Schauspieler ohne Filme:

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

Einige Leute (insbesondere MySQL-Leute) schreiben ANTI JOIN auch so:

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

Ich denke, der historische Grund ist die Leistung.

LATERAL JOIN

OMG, dieser ist zu cool. Ich bin der einzige, der es erwähnt? Hier ist eine coole Frage:

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

Es werden die TOP 5 Einnahmen gefunden, die Filme pro Schauspieler produzieren. Jedes Mal, wenn Sie eine TOP-N-per-etwas-Abfrage benötigen, LATERAL JOINwird Ihr Freund sein. Wenn Sie eine SQL Server-Person sind, kennen Sie diesen JOINTyp unter dem NamenAPPLY

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

OK, vielleicht ist das Betrug, weil ein LATERAL JOINoder APPLYAusdruck wirklich eine "korrelierte Unterabfrage" ist, die mehrere Zeilen erzeugt. Wenn wir aber "korrelierte Unterabfragen" zulassen, können wir auch über ...

MULTISET

Dies wird meines Wissens nur von Oracle und Informix implementiert, kann jedoch in PostgreSQL mithilfe von Arrays und / oder XML und in SQL Server mithilfe von XML emuliert werden.

MULTISETErzeugt eine korrelierte Unterabfrage und verschachtelt die resultierende Reihe von Zeilen in der äußeren Abfrage. Die folgende Abfrage wählt alle Schauspieler aus und sammelt für jeden Schauspieler ihre Filme in einer verschachtelten Sammlung:

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

Wie Sie gesehen haben, gibt es mehrere Arten von JOIN als nur die „langweilig“ INNER, OUTERund CROSS JOINdass in der Regel erwähnt werden. Weitere Details in meinem Artikel . Und bitte hören Sie auf, Venn-Diagramme zu verwenden, um sie zu veranschaulichen.


Equijoin ist der Sonderfall der Theta-Verbindung, bei der Theta Gleichheit ist. Die Theta-Verknüpfung ist analog zu einem speziellen Fall der inneren Verknüpfung, bei dem das Ein ein Theta-Vergleich einer Spalte von jeder ist. Einige Jahrzehnte nachdem Codd sie definiert hatte, definierten einige Lehrbücher Theta Join falsch als eine Verallgemeinerung, die das Analogon von Inner Join ist.
Philipxy

@philipxy: Gibt es etwas Spezielles, das ich in meiner Antwort ändern sollte? Sie könnten eine Bearbeitung vorschlagen ...
Lukas Eder

10

Ich habe eine Illustration erstellt, die meiner Meinung nach besser erklärt als Worte: Erklärungstabelle für SQL Join


@Niraj Die Kreise A & B enthalten nicht die Zeilen A & B. Sie werden ohne Gutschrift blind von einer anderen Stelle kopiert. Cross Join ist im Fall der inneren Verknüpfung enthalten, die innere Verknüpfung bei 1 = 1. Inwiefern sind diese Teile des Bildes "perfekt"?
Philipxy

@philipxy Sorry, aber es stört mich nicht, wenn es von woanders kopiert wird. und ich bin nicht sicher, was im obigen Bild nicht korrekt ist. für mich ist das ok Cross Join wird hier nicht beschrieben. Es ist nicht in einem inneren Join enthalten ..
Niraj

-3

Ich werde mein Haustier ärgern: das Schlüsselwort USING.

Wenn für beide Tabellen auf beiden Seiten von JOIN die Fremdschlüssel ordnungsgemäß benannt sind (dh derselbe Name, nicht nur "id"), kann dies verwendet werden:

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

Ich finde das sehr praktisch, lesbar und nicht oft genug verwendet.


2
Dies beantwortet die Frage nicht. Es gehört als Kommentar entweder unter die Frage oder eine der Antworten.
TylerH
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.