Antworten:
SQL JOIN
?SQL JOIN
ist eine Methode zum Abrufen von Daten aus zwei oder mehr Datenbanktabellen.
SQL JOIN
s?Es gibt insgesamt fünf JOIN
s. 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
In dieser Art von a erhalten JOIN
wir 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 JOIN
basiert auf der einzigen Tatsache, dass: NUR die übereinstimmenden Einträge in BEIDEN der Tabellen aufgelistet werden sollten.
Beachten Sie, dass eine JOIN
ohne andere JOIN
Schlüsselwörter (wie INNER
, OUTER
, LEFT
usw.) ein ist INNER JOIN
. Mit anderen Worten, JOIN
ist ein syntaktischer Zucker für INNER JOIN
(siehe: Unterschied zwischen JOIN und INNER 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 NULL
Werte zurückgegeben.
2.2 RECHTE AUSSENVERBINDUNG oder RECHTE VERBINDUNG
Dies JOIN
gibt 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 NULL
Werte zurückgegeben.
2.3 FULL OUTER JOIN oder FULL JOIN
Dies JOIN
kombiniert LEFT OUTER JOIN
und RIGHT OUTER JOIN
. Es gibt Zeilen aus beiden Tabellen zurück, wenn die Bedingungen erfüllt sind, und gibt den NULL
Wert zurück, wenn keine Übereinstimmung vorliegt .
Mit anderen Worten, OUTER JOIN
basiert 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`.
Es basiert auf den beiden Bedingungen:
JOIN
wird für alle gleichnamigen Spalten aus Gründen der Gleichheit erstellt.Dies scheint eher theoretischer Natur zu sein, und aus diesem Grund unterstützen (wahrscheinlich) die meisten DBMS dies nicht einmal.
Es ist das kartesische Produkt der beiden beteiligten Tabellen. Das Ergebnis von a CROSS JOIN
wird in den meisten Situationen keinen Sinn ergeben. Darüber hinaus brauchen wir das überhaupt nicht (oder am wenigsten, um genau zu sein).
Es ist nicht eine andere Form JOIN
, sondern es ist ein JOIN
( INNER
, OUTER
usw.) eine Tabelle mit mir selbst.
Abhängig vom Operator, der für eine JOIN
Klausel verwendet wird, kann es zwei Arten von JOIN
s geben. Sie sind
Aus welchem JOIN
Typ ( INNER
, OUTER
usw.), wenn wir nur den Gleichheitsoperator (=) verwenden, dann sagen wir , dass das JOIN
eine ist EQUI JOIN
.
Dies ist dasselbe wie EQUI JOIN
, erlaubt jedoch alle anderen Operatoren wie>, <,> = usw.
Viele betrachten beide
EQUI JOIN
und ThetaJOIN
ähnlich wieINNER
,OUTER
usw.JOIN
s. Aber ich glaube fest daran, dass es ein Fehler ist und die Ideen vage macht. DennINNER JOIN
,OUTER JOIN
etc sind alle mit den Tabellen und ihren Daten verbunden , währendEQUI JOIN
undTHETA JOIN
sind nur mit den Betreibern wir in der ehemaligen verwenden verbunden.Wieder gibt es viele, die
NATURAL JOIN
als eine Art "eigenartig" betrachtenEQUI JOIN
. In der Tat ist es wahr, wegen der ersten Bedingung, für die ich erwähnt habeNATURAL JOIN
. Wir müssen das jedoch nicht einfach aufNATURAL JOIN
s allein beschränken.INNER JOIN
s,OUTER JOIN
s etc könnte auch einEQUI JOIN
sein.
Definition:
Mit JOINS können Sie die Daten abfragen, die aus mehreren Tabellen gleichzeitig kombiniert wurden.
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.
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.
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.
CROSS-JOIN: Dieser Join wird nicht zusammengeführt / kombiniert, sondern führt ein kartesisches Produkt aus.
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.
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;
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.
UNION JOIN
. Jetzt veraltet in SQL: 2003.
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.
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:
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
An INNER JOIN
ist nur ein CROSS JOIN
Filter, bei dem das Filterprädikat Theta
in 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 INNER
optional ist (außer in MS Access).
( Beispiele für Ergebnisse finden Sie im Artikel. )
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.
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_UPDATE
Spalten in der Sakila-Datenbank ) kaum nützlich ist .
Hier ist die Syntax:
SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film
Jetzt OUTER JOIN
ist ein bisschen anders, INNER JOIN
als es eines UNION
von 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 OUTER
ist hier optional.
OUTER JOIN
gibt es in drei Geschmacksrichtungen:
LEFT [ OUTER ] JOIN
: Die linke Tabelle des JOIN
Ausdrucks wird wie oben gezeigt zur Vereinigung hinzugefügt.RIGHT [ OUTER ] JOIN
: Die rechte Tabelle des JOIN
Ausdrucks wird wie oben gezeigt zur Vereinigung hinzugefügt.FULL [ OUTER ] JOIN
: Beide Tabellen des JOIN
Ausdrucks 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 JOIN
kürzlich tatsächlich einen realen Anwendungsfall ).
Es gibt einige historische, veraltete Syntaxen in Oracle und SQL Server, die OUTER JOIN
bereits 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.
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 JOIN
auf der "anderen Seite des JOIN" übereinstimmt. Lange Rede, kurzer Sinn: Hiermit werden spärliche Daten in Berichten aufgefüllt. Sehr hilfreich!
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_id
Prä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.
Dies ist genau das Gegenteil von SEMI JOIN ( darauf achten, nicht zu verwenden , NOT IN
obwohl , 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.
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 JOIN
wird Ihr Freund sein. Wenn Sie eine SQL Server-Person sind, kennen Sie diesen JOIN
Typ 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 JOIN
oder APPLY
Ausdruck wirklich eine "korrelierte Unterabfrage" ist, die mehrere Zeilen erzeugt. Wenn wir aber "korrelierte Unterabfragen" zulassen, können wir auch über ...
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.
MULTISET
Erzeugt 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
, OUTER
und CROSS JOIN
dass 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.
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.