Oracle
 sql >> Base de données >  >> RDS >> Oracle

auto-jointure vs jointure interne

Je trouve utile de considérer toutes les tables d'une instruction SELECT comme représentant leurs propres ensembles de données.

Avant d'appliquer des conditions, vous pouvez considérer chaque ensemble de données comme étant complet (la table entière, par exemple).

Une jointure n'est qu'une des nombreuses façons de commencer à affiner ces ensembles de données pour trouver les informations que vous voulez vraiment.

Bien qu'un schéma de base de données puisse être conçu avec certaines relations à l'esprit (clé primaire <-> clé étrangère), ces relations n'existent réellement que dans le contexte d'une requête particulière. L'auteur de la requête peut relier ce qu'il veut à ce qu'il veut. Je donnerai un exemple plus tard...

Un INNER JOIN relie deux tables entre elles. Il y a souvent plusieurs opérations JOIN dans une requête pour enchaîner plusieurs tables. Cela peut devenir aussi compliqué que nécessaire. Pour un exemple simple, considérons les trois tableaux suivants...

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

La table STUDENT et la table CLASS ont été conçues pour être liées l'une à l'autre via la table INSCRIPTION. Ce type de table s'appelle une table de jonction .

Pour écrire une requête pour afficher tous les étudiants et les classes dans lesquelles ils sont inscrits, on utiliserait deux jointures internes...

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;

Lisez attentivement ce qui précède et vous devriez voir ce qui se passe. Vous obtiendrez en retour l'ensemble de données suivant...

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

En utilisant les clauses JOIN, nous avons limité les ensembles de données des trois tables à ceux qui correspondent les uns aux autres. Les "correspondances" sont définies à l'aide de ON clauses. Notez que si vous exécutiez cette requête, vous ne feriez pas voir la ligne CLASSID 4 de la table CLASS ou la ligne STUDENTID 1 de la table STUDENT car ces ID n'existent pas dans les correspondances (dans ce cas, la table ENROLLMENT). Examinez les jointures "LEFT"/"RIGHT"/"FULL OUTER" pour en savoir plus sur la façon de faire fonctionner cela un peu différemment.

Veuillez noter que, d'après mes commentaires sur les "relations" plus tôt, il n'y a aucune raison pourquoi vous ne pouviez pas exécuter une requête reliant la table STUDENT et la table CLASS directement sur les colonnes LASTNAME et PROFESSOR. Ces deux colonnes correspondent au type de données et, bien regardez ça ! Ils ont même une valeur en commun ! Ce serait probablement un ensemble de données étrange à obtenir en retour. Ce que je veux dire, c'est que cela peut être fait et que vous ne savez jamais quels besoins vous pourriez avoir à l'avenir pour des connexions intéressantes dans vos données. Comprenez la conception de la base de données, mais ne considérez pas les "relations" comme des règles qui ne peuvent être ignorées.

En attendant... SELF JOINS !

Considérez le tableau suivant...

PERSON

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

Si vous vous sentiez assez enclin à créer une base de données de toutes les personnes que vous connaissez et de celles qui appartiennent à la même famille, cela pourrait ressembler à cela.

Si vous vouliez renvoyer une personne, PERSONID 4, par exemple, vous écririez...

SELECT * FROM PERSON WHERE PERSONID = 4;

Vous apprendriez qu'il est dans la famille avec FAMILYID 2. Ensuite pour trouver tous des PERSONNES de sa famille vous écririez...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Fait et fait! SQL, bien sûr, peut accomplir cela en une seule requête en utilisant, vous l'avez deviné, un SELF JOIN.

Qu'est-ce qui déclenche vraiment le besoin d'un SELF JOIN voici que la table contient une colonne unique (PERSONID) et une colonne qui sert en quelque sorte de "Catégorie" (FAMILYID). Ce concept s'appelle Cardinalité et dans ce cas représente un un à plusieurs ou 1:M relation. Il n'y en a qu'un un de chaque PERSONNE mais il y en a beaucoup PERSONNES dans une FAMILLE .

Donc, ce que nous voulons retourner, c'est tout des membres d'une famille si un membre du PERSONID de la famille est connu...

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

Voici ce que vous obtiendriez...

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

Notons quelques choses. Les mots AUTO-JOIN ne se produisent nulle part. C'est parce qu'un SELF JOIN n'est qu'un concept. Le mot JOINDRE dans la requête ci-dessus aurait pu être une LEFT JOIN à la place et des choses différentes se seraient produites. L'intérêt d'un SELF JOIN est que vous utilisez deux fois la même table.

Considérez ma boîte à savon d'avant sur les ensembles de données. Ici, nous avons commencé deux fois avec l'ensemble de données de la table PERSON. Aucune instance de l'ensemble de données affecte l'autre sauf si nous disons que c'est le cas.

Commençons au bas de la requête. Le par L'ensemble de données est limité aux seules lignes où PERSONID =4. Connaissant la table, nous savons que cela renverra exactement une ligne. La colonne FAMILYID de cette ligne a une valeur de 2.

Dans la clause ON, nous limitons la fam ensemble de données (qui à ce stade est toujours la table PERSON entière) uniquement aux lignes où la valeur de FAMILYID correspond à une ou plusieurs des FAMILYIDs de par base de données. Comme nous en avons discuté, nous connaissons le par l'ensemble de données n'a qu'une seule ligne, donc une seule valeur FAMILYID. Par conséquent, la famille l'ensemble de données contient désormais uniquement les lignes où FAMILYID =2.

Enfin, en haut de la requête, nous sélectionnons toutes les lignes de la fam ensemble de données.

Voila ! Deux requêtes en une.

En conclusion, un INNER JOIN est l'un des nombreux types d'opérations JOIN. Je voudrais fortement nous vous suggérons de lire plus en détail les jointures externes LEFT, RIGHT et FULL OUTER (qui sont, collectivement, appelées OUTER JOINs ). Personnellement, j'ai raté une opportunité d'emploi pour avoir une faible connaissance des OUTER JOIN une fois et je ne laisserai pas cela se reproduire !

Une AUTO-JOINTURE est simplement n'importe quelle opération JOIN où vous reliez une table à elle-même. La façon dont vous choisissez de JOINDRE cette table à elle-même peut utiliser une INNER JOIN ou une OUTER JOIN. Notez qu'avec un SELF JOIN , pour ne pas confondre votre moteur SQL vous devez utilisez des alias de table (fam et per ci-dessus. Composez ce qui a du sens pour votre requête) ou il n'y a aucun moyen de différencier les différentes versions de la même table.

Maintenant que vous comprenez la différence, ouvrez grand votre esprit et réalisez qu'une seule requête peut contenir tous les différents types de JOIN à la fois. C'est juste une question de quelles données vous voulez et comment vous devez tordre et plier votre requête pour l'obtenir. Si vous vous retrouvez à exécuter une requête et à prendre le résultat de cette requête et à l'utiliser comme entrée d'une autre requête, vous pouvez probablement utiliser un JOIN pour en faire une requête à la place.

Pour jouer avec SQL, essayez de visiter W3Schools.com Il y a une base de données stockée localement avec un tas de tables conçues pour être liées les unes aux autres de différentes manières et elle est remplie de données ! Vous pouvez CREATE, DROP, INSERT, UPDATE et SELECT tout ce que vous voulez et remettre la base de données à sa valeur par défaut à tout moment. Essayez toutes sortes de SQL pour expérimenter différentes astuces. J'ai beaucoup appris là-bas, moi-même.

Désolé si c'était un peu verbeux, mais j'ai personnellement eu du mal avec le concept de JOIN quand j'ai commencé à apprendre SQL et expliquer un concept en utilisant un tas d'autres concepts complexes m'a enlisé. Il est parfois préférable de commencer par le bas.

J'espère que cela aide. Si vous pouvez mettre des JOIN dans votre poche arrière, vous pouvez faire de la magie avec SQL !

Bonne recherche !