Database
 sql >> Datenbank >  >> RDS >> Database

Ihr ultimativer Leitfaden für SQL Join:INNER JOIN – Teil 1

Inner Join, Outer Join, Cross Join? Was gibt?

Es ist eine berechtigte Frage. Ich habe einmal einen Visual Basic-Code mit darin eingebetteten T-SQL-Codes gesehen. Der VB-Code ruft Tabellendatensätze mit mehreren SELECT-Anweisungen ab, ein SELECT * pro Tabelle. Anschließend werden mehrere Resultsets zu einem Datensatz kombiniert. Absurd?

Für die jungen Entwickler, die es gemacht haben, war es das nicht. Aber als sie mich baten, zu bewerten, warum das System langsam war, war dieses Problem das erste, das meine Aufmerksamkeit erregte. Stimmt. Sie haben noch nie von SQL-Joins gehört. Um fair zu sein, sie waren ehrlich und offen für Vorschläge.

Wie beschreiben Sie SQL-Joins? Vielleicht erinnerst du dich an ein Lied – Imagine von John Lennon:

Sie mögen sagen, ich bin ein Träumer, aber ich bin nicht der einzige.

Ich hoffe, dass Sie sich uns eines Tages anschließen und die Welt eins sein wird.

Im Kontext des Liedes ist Verbinden gleichbedeutend mit Vereinen. In einer SQL-Datenbank bildet das Kombinieren von Datensätzen von 2 oder mehr Tabellen zu einer Ergebnismenge einen Join .

Dieser Artikel ist der Beginn einer dreiteiligen Serie über SQL-Joins:

  • INNER JOIN
  • OUTER JOIN, einschließlich LEFT, RIGHT und FULL
  • CROSS JOIN

Aber bevor wir anfangen, INNER JOIN zu diskutieren, wollen wir Joins im Allgemeinen beschreiben.

Mehr über SQL JOIN

Joins erscheinen direkt nach der FROM-Klausel. In seiner einfachsten Form sieht es so aus, als würde es den SQL-92-Standard verwenden:

FROM <table source> [<alias1>]
<join type> JOIN <table source> [<alias2>] [ON <join condition>] 
[<join type> JOIN <table source> [<alias3>] [ON <join condition>]
<join type> JOIN <table source> [<aliasN>] [ON <join condition>]]
[WHERE <condition>]

Lassen Sie uns die alltäglichen Dinge rund um den JOIN beschreiben.

Tabellenquellen

Laut Microsoft können Sie bis zu 256 Tabellenquellen hinzufügen. Dies hängt natürlich von Ihren Serverressourcen ab. Ich bin in meinem Leben nie mehr als 10 Tischen beigetreten, ganz zu schweigen von 256. Wie auch immer, Tabellenquellen können eine der folgenden sein:

  • Tabelle
  • Anzeigen
  • Tabellen- oder Ansichtssynonym
  • Tabellenvariable
  • Tabellenwertfunktion
  • Abgeleitete Tabelle

Tabellen-Alias

Ein Alias ​​ist optional, aber er verkürzt Ihren Code und minimiert den Tippaufwand. Es hilft Ihnen auch, Fehler zu vermeiden, wenn ein Spaltenname in zwei oder mehr Tabellen vorhanden ist, die in einem SELECT, UPDATE, INSERT oder DELETE verwendet werden. Es fügt Ihrem Code auch Klarheit hinzu. Es ist optional, aber ich würde die Verwendung von Aliasen empfehlen. (Außer Sie lieben es, Tabellenquellen nach Namen einzugeben.)

Beitrittsbedingung

Das ON-Schlüsselwort geht der Join-Bedingung voraus, die ein einzelner Join oder 2-Schlüssel-Spalten aus den 2 verknüpften Tabellen sein kann. Oder es kann sich um einen zusammengesetzten Join handeln, der mehr als zwei Schlüsselspalten verwendet. Es definiert, wie Tabellen miteinander in Beziehung stehen.

Wir verwenden die Join-Bedingung jedoch nur für INNER- und OUTER-Joins. Die Verwendung bei einem CROSS JOIN löst einen Fehler aus.

Da Join-Bedingungen die Beziehungen definieren, benötigen sie Operatoren.

Der häufigste Join-Bedingungsoperator ist der Gleichheitsoperator (=). Andere Operatoren wie> oder

SQL JOIN vs. Unterabfragen

Die meisten Joins können als Unterabfragen umgeschrieben werden und umgekehrt. Lesen Sie diesen Artikel, um mehr über Unterabfragen im Vergleich zu Verknüpfungen zu erfahren.

Joins und abgeleitete Tabellen

Die Verwendung abgeleiteter Tabellen in einem Join sieht folgendermaßen aus:

FROM table1 a
INNER JOIN (SELECT y.column3 from table2 x
            INNER JOIN table3 y on x.column1 = y.column1) b ON a.col1 = b.col2

Es wird aus dem Ergebnis einer anderen SELECT-Anweisung zusammengefügt und ist vollkommen gültig.

Sie werden noch mehr Beispiele haben, aber lassen Sie uns eine letzte Sache über SQL JOINS behandeln. So verarbeitet der Abfrageoptimierer von SQL Server Joins.

Wie SQL Server Joins verarbeitet

Um zu verstehen, wie der Prozess funktioniert, müssen Sie die beiden beteiligten Arten von Vorgängen kennen:

  • Logische Operationen entsprechen den in einer Abfrage verwendeten Join-Typen:INNER, OUTER oder CROSS. Sie als Entwickler definieren diesen Teil der Verarbeitung bei der Erstellung der Abfrage.
  • Physischer Betrieb – Der Abfrageoptimierer wählt die beste physische Operation aus, die für Ihren Join geeignet ist. Das Beste bedeutet am schnellsten Ergebnisse zu erzielen. Der Ausführungsplan Ihrer Abfrage zeigt die ausgewählten physischen Verknüpfungsoperatoren. Diese Operationen sind:
    • Nested-Loop-Join. Diese Operation ist schnell, wenn eine der beiden Tabellen klein und die zweite groß und indiziert ist. Es erfordert die wenigsten E/A-Vorgänge mit den wenigsten Vergleichen, ist aber nicht gut für große Ergebnismengen.
    • Verknüpfung zusammenführen. Dies ist die schnellste Operation für große und sortierte Ergebnismengen nach Spalten, die im Join verwendet werden.
    • Hash Join. Der Abfrageoptimierer verwendet es, wenn die Ergebnismenge für eine Nested Loop zu groß ist und die Eingaben für einen Merge-Join unsortiert sind. Ein Hash ist effizienter, als ihn zuerst zu sortieren und einen Merge-Join anzuwenden.
    • Adaptive Verknüpfung. Ab SQL Server 2017 ermöglicht es die Wahl zwischen einer verschachtelten Schleife oder einem Hash . Die Join-Methode wird verzögert, bis die erste Eingabe gescannt wird. Diese Operation wechselt dynamisch zu einem besseren physischen Join, ohne neu zu kompilieren.

Warum müssen wir uns damit beschäftigen?

Ein Wort:Leistung.

Eine Sache ist zu wissen, wie man Abfragen mit Verknüpfungen bildet, um korrekte Ergebnisse zu erzielen. Eine andere ist, es so schnell wie möglich laufen zu lassen. Sie müssen sich darum besonders kümmern, wenn Sie bei Ihren Benutzern einen guten Ruf haben möchten.

Worauf müssen Sie also im Ausführungsplan für diese logischen Operationen achten?

  • Angenommen, ein Sort-Operator steht vor dem Merge Join . Dieser Sortiervorgang ist für große Tabellen teuer (Abbildung 2). Sie können dies beheben, indem Sie die Eingabetabellen im Join vorsortieren.
  • Angenommen, es gibt Duplikate in den Eingabetabellen eines Merge-Joins . SQL Server schreibt die Duplikate der zweiten Tabelle in eine WorkTable in tempdb. Dann wird es die Vergleiche dort machen. Das STATISTICS IO zeigt alle beteiligten WorkTables an.
  • Wenn riesige Datenmengen in einem Hash-Job auf tempdb überlaufen in zeigt das STATISTICS IO einen großen logischen Lesevorgang für WorkFiles oder WorkTables. Eine Warnung wird auch im Ausführungsplan angezeigt (Abbildung 3). Sie können zwei Dinge anwenden:die Eingabetabellen vorsortieren oder die Joins verringern, wenn möglich. Daher kann der Abfrageoptimierer einen anderen physischen Join auswählen.

Beitrittshinweise

Join-Hinweise sind neu in SQL Server 2019. Wenn Sie sie in Ihren Joins verwenden, weist sie den Abfrageoptimierer an, nicht mehr zu entscheiden, was für die Abfrage am besten ist. Sie sind der Chef, wenn es um die physische Verknüpfung geht.

Jetzt hör auf, genau dort. Die Wahrheit ist, dass der Abfrageoptimierer normalerweise den besten physischen Join für Ihre Abfrage auswählt. Wenn Sie nicht wissen, was Sie tun, verwenden Sie keine Join-Hinweise.

Die möglichen Hinweise, die Sie angeben können, sind LOOP, MERGE, HASH oder REMOTE.

Ich habe keine Join-Hinweise verwendet, aber hier ist die Syntax:


<join type> <join hint> JOIN <table source> [<alias>] ON <join condition>

Alles über INNER JOIN

INNER JOIN gibt basierend auf einer Bedingung die Zeilen mit übereinstimmenden Datensätzen in beiden Tabellen zurück. Es ist auch der Standard-Join, wenn Sie das Schlüsselwort INNER:

nicht angeben

Wie Sie sehen, übereinstimmende Zeilen aus Table1 und Tabelle2 werden mit Key1 zurückgegeben als Join-Bedingung. Die Tabelle1 Datensatz mit Key1 =„C“ wird ausgeschlossen, da es keine übereinstimmenden Datensätze in Tabelle2 gibt .

Immer wenn ich eine Abfrage bilde, ist meine erste Wahl INNER JOIN. OUTER JOIN kommt nur, wenn es die Anforderungen erfordern.

INNER JOIN-Syntax

In T-SQL werden zwei INNER JOIN-Syntaxen unterstützt:SQL-92 und SQL-89.

SQL-92 INNER JOIN

FROM <table source1> [<alias1>]
INNER JOIN <table source2> [<alias2>] ON <join condition1>
[INNER JOIN <table source3> [<alias3>] ON <join condition2>
 INNER JOIN <table sourceN> [<aliasN>] ON <join conditionN>]
[WHERE <condition>]

SQL-89 INNER JOIN

FROM <table source1> [alias1], <table source2> [alias2] [, <table source3> [alias3], <table sourceN> [aliasN]]
WHERE (<join condition1>)
[AND (<join condition2>)
AND (<join condition3>)
AND (<join conditionN>)]

Welche INNER JOIN-Syntax ist besser?

Die erste Join-Syntax, die ich gelernt habe, war SQL-89. Als SQL-92 endlich ankam, fand ich es zu langatmig. Ich dachte auch, da die Ausgabe dieselbe war, warum sollte man sich die Mühe machen, mehr Schlüsselwörter einzugeben? Ein grafischer Abfrage-Designer hatte den generierten Code SQL-92, und ich habe ihn wieder in SQL-89 geändert. Aber heute bevorzuge ich SQL-92, auch wenn ich mehr tippen muss. Hier ist der Grund:

  • Die Absicht des Join-Typs ist klar. Der nächste Typ, der meinen Code pflegt, wird wissen, was in der Abfrage beabsichtigt ist.
  • Das Vergessen der Join-Bedingung in einer SQL-92-Syntax löst einen Fehler aus. In der Zwischenzeit wird das Vergessen der Join-Bedingung in SQL-89 als CROSS JOIN behandelt. Wenn ich einen INNER- oder OUTER-Join meinte, wäre dies ein unbemerkter Logikfehler, bis sich die Benutzer beschweren.
  • Neue Tools neigen eher zu SQL-92. Wenn ich jemals wieder einen grafischen Abfrage-Designer verwende, muss ich ihn nicht auf SQL-89 ändern. Ich bin nicht mehr stur, also ist meine Herzfrequenz wieder normal. Ein Hoch auf mich.

Die oben genannten Gründe sind meine. Sie haben vielleicht Ihre Gründe, warum Sie SQL-92 bevorzugen oder warum Sie es hassen. Ich frage mich, was das für Gründe sind. Lassen Sie es mich im Kommentarbereich unten wissen.

Aber wir können diesen Artikel nicht ohne Beispiele und Erklärungen beenden.

10 INNER JOIN-Beispiele

1. Verbinden von 2 Tischen

Hier ist ein Beispiel für 2 Tabellen, die mit INNER JOIN in SQL-92-Syntax miteinander verbunden wurden.

-- Display Vests, Helmets, and Light products

USE AdventureWorks
GO

SELECT
 p.ProductID
,P.Name AS [Product]
,ps.ProductSubcategoryID
,ps.Name AS [ProductSubCategory]
FROM Production.Product p
INNER JOIN Production.ProductSubcategory ps ON P.ProductSubcategoryID = ps.ProductSubcategoryID
WHERE P.ProductSubcategoryID IN (25, 31, 33);  -- for vest, helmet, and light 
                                            -- product subcategories

Sie geben nur die Spalten an, die Sie benötigen. Im obigen Beispiel sind 4 Spalten angegeben. Ich weiß, dass es zu langwierig ist als SELECT *, aber denken Sie daran:Es ist die beste Vorgehensweise.

Beachten Sie auch die Verwendung von Tabellenaliasen. Sowohl das Produkt und ProductSubcategory Tabellen haben eine Spalte namens [Name ]. Wenn Sie den Alias ​​nicht angeben, wird ein Fehler ausgelöst.

Hier ist die entsprechende SQL-89-Syntax:

-- Display Vests, Helmets, and Light products

USE AdventureWorks
GO

SELECT
 p.ProductID
,P.Name AS [Product]
,ps.ProductSubcategoryID
,ps.Name AS [ProductSubCategory]
FROM Production.Product p, Production.ProductSubcategory ps 
WHERE P.ProductSubcategoryID = ps.ProductSubcategoryID
AND P.ProductSubcategoryID IN (25, 31, 33);

Sie sind bis auf die in der WHERE-Klausel mit einem AND-Schlüsselwort gemischte Join-Bedingung identisch. Aber sind sie unter der Haube wirklich gleich? Sehen wir uns die Ergebnismenge, den STATISTICS IO und den Execution Plan an.

Sehen Sie sich die Ergebnismenge von 9 Datensätzen an:

Es sind nicht nur die Ergebnisse, sondern auch die von SQL Server benötigten Ressourcen.

Siehe die logischen Lesevorgänge:

Schließlich offenbart der Ausführungsplan denselben Abfrageplan für beide Abfragen, wenn ihre QueryPlanHashes sind gleich. Beachten Sie auch die hervorgehobenen Operationen im Diagramm:

Basierend auf den Ergebnissen ist die SQL Server-Abfrageverarbeitung gleich, egal ob es sich um SQL-92 oder SQL-89 handelt. Aber wie gesagt, die Übersichtlichkeit in SQL-92 ist für mich viel besser.

Abbildung 7 zeigt auch einen im Plan verwendeten Nested Loop Join. Wieso den? Die Ergebnismenge ist klein.

2. Beitritt zu mehreren Tischen

Sehen Sie sich die folgende Abfrage mit 3 verknüpften Tabellen an.

-- Get the total number of orders per Product Category
USE AdventureWorks
GO

SELECT
 ps.Name AS ProductSubcategory
,SUM(sod.OrderQty) AS TotalOrders
FROM Production.Product p
INNER JOIN Sales.SalesOrderDetail sod ON P.ProductID = sod.ProductID
INNER JOIN Sales.SalesOrderHeader soh ON sod.SalesOrderID = soh.SalesOrderID
INNER JOIN Production.ProductSubcategory ps ON p.ProductSubcategoryID = ps.ProductSubcategoryID
WHERE soh.OrderDate BETWEEN '1/1/2014' AND '12/31/2014'
AND p.ProductSubcategoryID IN (1,2)
GROUP BY ps.Name
HAVING ps.Name IN ('Mountain Bikes', 'Road Bikes')

3. Zusammengesetzter Join

Sie können auch 2 Tische verbinden, indem Sie 2 Schlüssel verwenden, um sie in Beziehung zu setzen. Sehen Sie sich das Beispiel unten an. Es verwendet 2 Join-Bedingungen mit einem UND-Operator.

SELECT
 a.column1
,b.column1
,b.column2
FROM Table1 a
INNER JOIN Table2 b ON a.column1 = b.column1 AND a.column2 = b.column2

4. INNER JOIN Verwenden eines physikalischen Joins mit verschachtelten Schleifen

Im Beispiel unten das Produkt Tabelle hat 9 Datensätze – eine kleine Menge. Die verbundene Tabelle ist SalesOrderDetail – ein großes Set. Der Abfrageoptimierer verwendet einen Nested-Loop-Join, wie in Abbildung 8 gezeigt.

USE AdventureWorks
GO

SELECT
 sod.SalesOrderDetailID
,sod.ProductID
,P.Name
,P.ProductNumber
,sod.OrderQty
FROM Sales.SalesOrderDetail sod
INNER JOIN Production.Product p ON sod.ProductID = p.ProductID
WHERE P.ProductSubcategoryID IN(25, 31, 33);

5. INNER JOIN Verwenden eines Merge Physical Joins

Das folgende Beispiel verwendet einen Merge-Join, da beide Eingabetabellen nach SalesOrderID sortiert sind.

SELECT
 soh.SalesOrderID
,soh.OrderDate
,sod.SalesOrderDetailID
,sod.ProductID
,sod.LineTotal
FROM Sales.SalesOrderHeader soh
INNER JOIN sales.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID

6. INNER JOIN mit einem physischen Hash-Join

Das folgende Beispiel verwendet einen Hash-Join:

SELECT
 s.Name AS Store
,SUM(soh.TotalDue) AS TotalSales
FROM Sales.SalesOrderHeader soh
INNER JOIN Sales.Store s ON soh.SalesPersonID = s.SalesPersonID
GROUP BY s.Name

7. INNER JOIN Adaptive Physical Join verwenden

Im Beispiel unten der SalesPerson Tabelle hat einen Non-clustered ColumnStore Index auf der TerritoryID Säule. Der Abfrageoptimierer entschied sich für einen Nested-Loop-Join, wie in Abbildung 11 gezeigt.

SELECT
sp.BusinessEntityID
,sp.SalesQuota
,st.Name AS Territory
FROM Sales.SalesPerson sp
INNER JOIN Sales.SalesTerritory st ON sp.TerritoryID = st.TerritoryID
WHERE sp.TerritoryID BETWEEN 1 AND 5

8. Zwei Möglichkeiten, eine Unterabfrage in einen INNER JOIN umzuschreiben

Betrachten Sie diese Anweisung mit einer verschachtelten Unterabfrage:

SELECT [SalesOrderID], [OrderDate], [ShipDate], [CustomerID]
FROM Sales.SalesOrderHeader 
WHERE [CustomerID] IN (SELECT [CustomerID] FROM Sales.Customer
			WHERE PersonID IN (SELECT BusinessEntityID FROM Person.Person
                                          WHERE lastname LIKE N'I%' AND PersonType='SC'))

Die gleichen Ergebnisse können herauskommen, wenn Sie ihn wie folgt in einen INNER JOIN ändern:

SELECT o.[SalesOrderID], o.[OrderDate], o.[ShipDate], o.[CustomerID]
FROM Sales.SalesOrderHeader o
INNER JOIN Sales.Customer c on o.CustomerID = c.CustomerID
INNER JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
WHERE p.PersonType = 'SC'
AND p.lastname LIKE N'I%'

Eine andere Möglichkeit zum Umschreiben besteht darin, eine abgeleitete Tabelle als Tabellenquelle für den INNER JOIN zu verwenden:

SELECT o.[SalesOrderID], o.[OrderDate], o.[ShipDate], o.[CustomerID]
FROM Sales.SalesOrderHeader o
INNER JOIN (SELECT c.CustomerID, P.PersonType, P.LastName
            FROM Sales.Customer c
            INNER JOIN Person.Person p ON c.PersonID = P.BusinessEntityID
	      WHERE p.PersonType = 'SC'
	        AND p.LastName LIKE N'I%') AS q ON o.CustomerID = q.CustomerID

Alle 3 Abfragen geben dieselben 48 Datensätze aus.

9. Join-Hinweise verwenden

Die folgende Abfrage verwendet eine verschachtelte Schleife:

SELECT
 sod.SalesOrderDetailID
,sod.ProductID
,P.Name
,P.ProductNumber
,sod.OrderQty
FROM Sales.SalesOrderDetail sod
INNER JOIN Production.Product p ON sod.ProductID = p.ProductID
WHERE P.ProductSubcategoryID IN(25, 31, 33);

Wenn Sie einen Hash-Join erzwingen möchten, geschieht Folgendes:

SELECT
 sod.SalesOrderDetailID
,sod.ProductID
,P.Name
,P.ProductNumber
,sod.OrderQty
FROM Sales.SalesOrderDetail sod
INNER HASH JOIN Production.Product p ON sod.ProductID = p.ProductID
WHERE P.ProductSubcategoryID IN(25, 31, 33);

Beachten Sie jedoch, dass STATISTICS IO zeigt, dass die Leistung schlecht wird, wenn Sie einen Hash-Join erzwingen.

In der Zwischenzeit verwendet die folgende Abfrage einen Merge Join:

SELECT
 soh.SalesOrderID
,soh.OrderDate
,sod.SalesOrderDetailID
,sod.ProductID
,sod.LineTotal
FROM Sales.SalesOrderHeader soh
INNER JOIN sales.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID

So wird es, wenn Sie es zu einer verschachtelten Schleife zwingen:

SELECT
 soh.SalesOrderID
,soh.OrderDate
,sod.SalesOrderDetailID
,sod.ProductID
,sod.LineTotal
FROM Sales.SalesOrderHeader soh
INNER LOOP JOIN sales.SalesOrderDetail sod ON soh.SalesOrderID = sod.SalesOrderID

Nach dem Überprüfen des STATISTICS IO von beiden erfordert das Erzwingen einer verschachtelten Schleife mehr Ressourcen zum Verarbeiten der Abfrage:

Daher sollte die Verwendung von Join-Hinweisen Ihr letzter Ausweg sein, wenn Sie die Leistung optimieren. Überlassen Sie dies Ihrem SQL Server.

10. Verwendung von INNER JOIN in UPDATE

Sie können INNER JOIN auch in einer UPDATE-Anweisung verwenden. Hier ist ein Beispiel:

UPDATE Sales.SalesOrderHeader
SET ShipDate = getdate() 
FROM Sales.SalesOrderHeader o
INNER JOIN Sales.Customer c on o.CustomerID = c.CustomerID
INNER JOIN Person.Person p ON c.PersonID = p.BusinessEntityID
WHERE p.PersonType = 'SC'

Da es möglich ist, einen Join in einem UPDATE zu verwenden, warum probieren Sie es nicht mit DELETE und INSERT aus?

SQL Join und INNER JOIN Takeaways

Also, was ist das Besondere am SQL-Join?

  • Ein SQL JOIN kombiniert Datensätze von 2 oder mehr Tabellen, um eine Ergebnismenge zu bilden.
  • Es gibt Arten von Joins in SQL:INNER, OUTER und CROSS.
  • Als Entwickler oder Administrator entscheiden Sie, welche logischen Operationen oder Join-Typen Sie für Ihre Anforderungen verwenden möchten.
  • Auf der anderen Seite entscheidet der Abfrageoptimierer über die besten zu verwendenden physikalischen Join-Operatoren. Es kann Nested Loop, Merge, Hash oder Adaptive sein.
  • Sie können Verknüpfungshinweise verwenden, um zu erzwingen, welche physische Verknüpfung verwendet werden soll, aber dies sollte Ihr letzter Ausweg sein. In den meisten Fällen ist es besser, dies Ihrem SQL-Server zu überlassen.
  • Die Kenntnis der physikalischen Verknüpfungsoperatoren hilft Ihnen auch bei der Optimierung der Abfrageleistung.
  • Außerdem können Unterabfragen mithilfe von Joins umgeschrieben werden.

In der Zwischenzeit zeigte dieser Beitrag 10 Beispiele für INNER JOINs. Es sind nicht nur Beispielcodes. Einige von ihnen beinhalten auch eine Inspektion, wie der Code von innen nach außen funktioniert. Es soll Ihnen nicht nur beim Programmieren helfen, sondern auch dabei helfen, auf die Leistung zu achten. Am Ende sollen die Ergebnisse nicht nur stimmen, sondern auch schnell geliefert werden.

Wir sind noch nicht fertig. Der nächste Artikel befasst sich mit OUTER JOINS. Bleiben Sie dran.

Siehe auch

Mit SQL-Joins können Sie Daten aus mehr als einer Tabelle abrufen und kombinieren. Sehen Sie sich dieses Video an, um mehr über SQL-Joins zu erfahren.