Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Self-Join vs. Inner-Join

Ich finde es hilfreich, sich vorzustellen, dass alle Tabellen in einer SELECT-Anweisung ihre eigenen Datensätze darstellen.

Bevor Sie Bedingungen angewendet haben, können Sie sich vorstellen, dass jeder Datensatz vollständig ist (z. B. die gesamte Tabelle).

Ein Join ist nur eine von mehreren Möglichkeiten, mit der Verfeinerung dieser Datensätze zu beginnen, um die Informationen zu finden, die Sie wirklich benötigen.

Obwohl ein Datenbankschema unter Berücksichtigung bestimmter Beziehungen (Primärschlüssel <-> Fremdschlüssel) entworfen werden kann, existieren diese Beziehungen wirklich nur im Kontext einer bestimmten Abfrage. Der Abfrageschreiber kann alles, was er will, mit allem in Beziehung setzen, was er will. Ich werde später ein Beispiel dafür geben...

Ein INNER JOIN verbindet zwei Tabellen miteinander. Es gibt oft mehrere JOIN-Operationen in einer Abfrage, um mehrere Tabellen zu verketten. Es kann so kompliziert werden, wie es sein muss. Betrachten Sie als einfaches Beispiel die folgenden drei Tabellen...

STUDENT

| STUDENTID | LASTNAME | FIRSTNAME |
------------------------------------
      1     |  Smith   |   John
      2     |  Patel   |  Sanjay
      3     |   Lee    |  Kevin
      4     |  Jackson |  Steven
ENROLLMENT

| ENROLLMENT ID | STUDENTID | CLASSID |
---------------------------------------
        1       |     2     |    3
        2       |     3     |    1
        3       |     4     |    2
CLASS

| CLASSID | COURSE | PROFESSOR |
--------------------------------
     1    | CS 101 |   Smith
     2    | CS 201 |  Ghandi
     3    | CS 301 |  McDavid
     4    | CS 401 |  Martinez

Die Tabelle STUDENT und die Tabelle CLASS wurden so entworfen, dass sie über die Tabelle ENROLLMENT miteinander in Beziehung stehen. Diese Art von Tabelle wird als Verbindungstabelle bezeichnet .

Um eine Abfrage zu schreiben, um alle Schüler und die Klassen anzuzeigen, in denen sie eingeschrieben sind, würde man zwei verwenden innere Joins...

SELECT stud.LASTNAME, stud.FIRSTNAME, class.COURSE, class.PROFESSOR
FROM STUDENT stud
INNER JOIN ENROLLMENT enr
    ON stud.STUDENTID = enr.STUDENTID
INNER JOIN CLASS class
    ON class.CLASSID = enr.CLASSID;

Lesen Sie das Obige genau durch und Sie sollten sehen, was passiert. Als Gegenleistung erhalten Sie folgenden Datensatz...

 | LASTNAME | FIRSTNAME | COURSE | PROFESSOR |
 ---------------------------------------------
     Patel  |   Sanjay  | CS 301 |  McDavid
      Lee   |   Kevin   | CS 101 |   Smith
    Jackson |  Steven   | CS 201 |  Ghandi

Mit den JOIN-Klauseln haben wir die Datensätze aller drei Tabellen auf diejenigen beschränkt, die zueinander passen. Die "Matches" werden mit dem ON definiert Klauseln. Beachten Sie, dass Sie diese Abfrage nicht ausführen würden sehen Sie sich die Zeile CLASSID 4 aus der Tabelle CLASS oder die Zeile STUDENTID 1 aus der Tabelle STUDENT an, da diese IDs in den Übereinstimmungen (in diesem Fall der Tabelle ENROLLMENT) nicht vorhanden sind. Sehen Sie sich "LEFT"/"RIGHT"/"FULL OUTER" JOINs an, um mehr darüber zu erfahren, wie Sie das etwas anders machen können.

Bitte beachten Sie, dass es laut meinen Kommentaren zu "Beziehungen" vorhin keinen Grund gibt warum Sie keine Abfrage ausführen konnten, die die Tabellen STUDENT und KLASSE direkt auf die Spalten NACHNAME und PROFESSOR bezieht. Diese beiden Spalten stimmen im Datentyp überein und sehen Sie sich das an! Sie haben sogar einen gemeinsamen Wert! Dies wäre wahrscheinlich ein seltsamer Datensatz, den man im Gegenzug bekommen würde. Mein Punkt ist, dass es machbar ist und Sie nie wissen, welche Bedürfnisse Sie in Zukunft nach interessanten Verbindungen in Ihren Daten haben könnten. Verstehen Sie das Design der Datenbank, aber denken Sie nicht an "Beziehungen" als Regeln, die nicht ignoriert werden können.

In der Zwischenzeit... SELBST BEITRETEN!

Betrachten Sie die folgende Tabelle...

PERSON

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      1    |     1    |  John
      2    |     1    | Brynn
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim
      6    |     3    | Becca

Wenn Sie so geneigt sind, eine Datenbank aller Personen zu erstellen, die Sie kennen und die zur selben Familie gehören, könnte dies so aussehen.

Wenn Sie beispielsweise eine Person zurückgeben möchten, PERSONID 4, schreiben Sie...

SELECT * FROM PERSON WHERE PERSONID = 4;

Sie würden erfahren, dass er in der Familie mit FAMILYID 2 ist. Dann finden Sie alle der PERSONEN in seiner Familie würden Sie schreiben...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Gemacht und gemacht! SQL kann dies natürlich in einer einzigen Abfrage bewerkstelligen, indem Sie, Sie haben es erraten, einen SELF JOIN verwenden.

Was wirklich die Notwendigkeit für einen SELF JOIN auslöst Hier ist, dass die Tabelle eine eindeutige Spalte (PERSONID) und eine Spalte enthält, die als eine Art "Kategorie" (FAMILYID) dient. Dieses Konzept wird Kardinalität genannt und steht in diesem Fall für eins zu viele oder 1:M Beziehung. Es gibt nur eine jeder PERSON aber es gibt viele PERSONEN in einer FAMILIE .

Wir möchten also alles zurückgeben der Familienmitglieder, falls eines PERSONID des Familienmitglieds ist bekannt...

SELECT fam.*
FROM PERSON per
JOIN PERSON fam
    ON per.FamilyID = fam.FamilyID
WHERE per.PERSONID = 4;

Hier ist, was Sie bekommen würden...

| PERSONID | FAMILYID |  NAME  |
--------------------------------
      3    |     2    | Arpan
      4    |     2    | Steve
      5    |     2    |  Tim

Halten wir ein paar Dinge fest. Die Wörter SELF JOIN kommen nirgends vor. Das liegt daran, dass es sich um einen SELF JOIN handelt ist nur ein Konzept. Das Wort MITGLIED in der obigen Abfrage hätte ein LEFT JOIN sein können stattdessen wären andere Dinge passiert. Der Sinn eines SELF JOIN ist, dass Sie dieselbe Tabelle zweimal verwenden.

Betrachten Sie meine Seifenkiste von vorher auf Datensätze. Hier haben wir zweimal mit dem Datensatz aus der Tabelle PERSON begonnen. Weder Instanz des Datensatzes wirkt sich auf den anderen aus, es sei denn, wir sagen, dass dies der Fall ist.

Beginnen wir am Ende der Abfrage. Die pro Der Datensatz wird nur auf die Zeilen beschränkt, in denen PERSONID =4 ist. Da wir die Tabelle kennen, wissen wir, dass sie genau eine Zeile zurückgibt. Die Spalte FAMILYID in dieser Zeile hat den Wert 2.

In der ON-Klausel begrenzen wir die fam Datensatz (der zu diesem Zeitpunkt immer noch die gesamte PERSON-Tabelle ist) nur auf die Zeilen, in denen der Wert von FAMILYID mit eins oder mehr übereinstimmt der FAMILYIDs des pro Datensatz. Wie wir besprochen haben, kennen wir das pro Datensatz hat nur eine Zeile, daher einen FAMILYID-Wert. Daher die fam Datensatz enthält jetzt nur noch Zeilen mit FAMILYID =2.

Schließlich wählen wir oben in der Abfrage alle Zeilen in fam aus Datensatz.

Voila! Zwei Abfragen in einer.

Zusammenfassend ein INNER JOIN ist eine von mehreren Arten von JOIN-Operationen. Ich würde stark schlagen vor, sich weiter mit LEFT, RIGHT und FULL OUTER JOINs zu befassen (die gemeinsam als OUTER JOINs bezeichnet werden ). Ich persönlich habe eine Arbeitsgelegenheit verpasst, weil ich einmal ein schwaches Wissen über OUTER JOINs hatte, und werde es nicht noch einmal passieren lassen!

EIN SELBSTVERBINDUNG ist einfach jede JOIN-Operation, bei der Sie eine Tabelle mit sich selbst in Beziehung setzen. Die Art und Weise, wie Sie diese Tabelle mit sich selbst VERKNÜPFEN, kann einen INNER JOIN verwenden oder ein OUTER JOIN. Beachten Sie dies bei einem SELF JOIN , um Ihre SQL-Engine nicht zu verwirren, müssen Sie Verwenden Sie Tabellenaliase (fam und pro von oben. Erfinden Sie, was für Ihre Abfrage sinnvoll ist), oder es gibt keine Möglichkeit, die verschiedenen Versionen zu unterscheiden derselben Tabelle.

Jetzt, da Sie den Unterschied verstehen, öffnen Sie Ihren Geist ganz weit und erkennen Sie, dass eine einzige Abfrage alle verschiedenen Arten von JOINs gleichzeitig enthalten kann. Es geht nur darum, welche Daten Sie wollen und wie Sie Ihre Abfrage drehen und biegen müssen, um sie zu erhalten. Wenn Sie feststellen, dass Sie eine Abfrage ausführen und das Ergebnis dieser Abfrage als Eingabe für eine andere Abfrage verwenden, können Sie wahrscheinlich einen JOIN verwenden um es stattdessen zu einer Abfrage zu machen.

Um mit SQL herumzuspielen, besuchen Sie W3Schools.com Dort gibt es eine lokal gespeicherte Datenbank mit einer Reihe von Tabellen, die so konzipiert sind, dass sie auf verschiedene Weise miteinander in Beziehung stehen, und die mit Daten gefüllt ist! Sie können alles, was Sie wollen, ERSTELLEN, LÖSCHEN, EINFÜGEN, AKTUALISIEREN und AUSWÄHLEN und die Datenbank jederzeit auf ihre Standardwerte zurücksetzen. Probieren Sie alle Arten von SQL aus, um mit verschiedenen Tricks zu experimentieren. Ich habe dort selbst viel gelernt.

Tut mir leid, wenn dies etwas wortreich war, aber ich persönlich hatte mit dem Konzept von JOINs zu kämpfen, als ich anfing, SQL zu lernen, und die Erklärung eines Konzepts durch die Verwendung einer Reihe anderer komplexer Konzepte hat mich gebremst. Fangen Sie manchmal am besten ganz unten an.

Ich hoffe, es hilft. Wenn Sie JOINs in Ihre Gesäßtasche stecken können, können Sie mit SQL zaubern!

Viel Spaß beim Abfragen!