sql >> Database >  >> RDS >> Oracle

zelf join vs inner join

Ik vind het handig om te denken aan alle tabellen in een SELECT-statement als representatief voor hun eigen datasets.

Voordat je voorwaarden hebt toegepast, kun je elke dataset als compleet beschouwen (bijvoorbeeld de hele tabel).

Een join is slechts een van de vele manieren om die datasets te verfijnen om de informatie te vinden die u echt wilt.

Hoewel een databaseschema kan worden ontworpen met bepaalde relaties in gedachten (primaire sleutel <-> Foreign Key), bestaan ​​deze relaties eigenlijk alleen in de context van een bepaalde query. De queryschrijver kan alles wat hij wil relateren aan wat hij maar wil. Ik zal hier later een voorbeeld van geven...

Een INNER JOIN koppelt twee tabellen aan elkaar. Er zijn vaak meerdere JOIN-bewerkingen in één query om meerdere tabellen aan elkaar te koppelen. Het kan zo ingewikkeld worden als nodig is. Bekijk voor een eenvoudig voorbeeld de volgende drie 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

De STUDENT-tabel en de CLASS-tabel zijn ontworpen om met elkaar in verband te staan ​​via de ENROLLMENT-tabel. Dit soort tabel wordt een Verbindingstabel genoemd .

Om een ​​query te schrijven om alle studenten en de klassen waarin ze zijn ingeschreven weer te geven, zou men twee . gebruiken inner 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;

Lees het bovenstaande aandachtig en je zou moeten zien wat er gebeurt. Wat je ervoor terugkrijgt is de volgende dataset...

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

Met behulp van de JOIN-clausules hebben we de datasets van alle drie de tabellen beperkt tot alleen de tabellen die met elkaar overeenkomen. De "overeenkomsten" worden gedefinieerd met de AAN clausules. Houd er rekening mee dat als u deze zoekopdracht uitvoert, u niet zie de rij CLASSID 4 uit de tabel CLASS of de rij STUDENTID 1 uit de tabel STUDENT omdat die ID's niet voorkomen in de overeenkomsten (in dit geval de tabel ENROLLMENT). Kijk in "LEFT"/"RIGHT"/"FULL OUTER" JOINs voor meer informatie over hoe je dat een beetje anders kunt laten werken.

Let op, volgens mijn eerdere opmerkingen over "relaties" is er geen reden waarom je een query met betrekking tot de STUDENT-tabel en de CLASS-tabel niet rechtstreeks op de LASTNAME- en PROFESSOR-kolommen kon uitvoeren. Die twee kolommen komen overeen in gegevenstype en kijk daar eens naar! Ze hebben zelfs een gemeenschappelijke waarde! Dit zou waarschijnlijk een rare dataset zijn om in ruil daarvoor te krijgen. Mijn punt is dat het kan en je weet nooit wat je in de toekomst nodig hebt voor interessante verbindingen in je data. Begrijp het ontwerp van de database, maar beschouw 'relaties' niet als regels die niet kunnen worden genegeerd.

In de tussentijd... ZELF DEELT ZICH AAN!

Bekijk de volgende tabel...

PERSON

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

Als je de neiging zou hebben om een ​​database te maken van alle mensen die je kent en welke tot dezelfde familie behoren, dan zou het er zo uit kunnen zien.

Als u één persoon wilt retourneren, bijvoorbeeld PERSONID 4, schrijft u...

SELECT * FROM PERSON WHERE PERSONID = 4;

Je zou leren dat hij in de familie is met FAMILYID 2. Dan om alle te vinden van de PERSONEN in zijn familie zou je schrijven...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Klaar en klaar! SQL kan dit natuurlijk in één query bereiken met, je raadt het al, een SELF JOIN.

Wat echt de behoefte aan een SELF JOIN veroorzaakt hier is dat de tabel een unieke kolom (PERSONID) bevat en een kolom die dient als een soort "Categorie" (FAMILYID). Dit concept heet Kardinaliteit en in dit geval staat voor een één op veel of 1:M relatie. Er is maar één van elke PERSOON maar er zijn veel PERSONEN in een FAMILIE .

Dus wat we willen teruggeven is alles van de leden van een gezin indien één PERSONID van het gezin is bekend...

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

Dit is wat je zou krijgen...

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

Laten we een paar dingen opmerken. De woorden SELF JOIN komen nergens voor. Dat komt omdat een SELF JOIN is maar een concept. Het woord DOEN in de bovenstaande zoekopdracht had een LEFT JOIN . kunnen zijn in plaats daarvan en er zouden andere dingen zijn gebeurd. Het punt van een SELF JOIN is dat je dezelfde tabel twee keer gebruikt.

Denk aan mijn zeepkist van vroeger op datasets. Hier zijn we twee keer begonnen met de dataset uit de tabel PERSON. Geen van beide instantie van de dataset beïnvloedt de andere, tenzij we zeggen van wel.

Laten we onderaan de query beginnen. De per dataset wordt beperkt tot alleen die rijen waar PERSONID =4. Als we de tabel kennen, weten we dat die precies één rij zal retourneren. De FAMILYID-kolom in die rij heeft een waarde van 2.

In de ON-clausule beperken we de fam dataset (die op dit moment nog steeds de hele PERSON-tabel is) naar alleen die rijen waar de waarde van FAMILYID overeenkomt met een of meer van de FAMILYID's van de per gegevensverzameling. Zoals we hebben besproken, kennen we de per dataset heeft slechts één rij, dus één FAMILYID-waarde. Daarom de fam dataset bevat nu alleen rijen waar FAMILYID =2.

Ten slotte selecteren we bovenaan de zoekopdracht alle rijen in de fam gegevensset.

Voila! Twee zoekopdrachten in één.

Kortom, een INNER JOIN is een van de verschillende soorten JOIN-bewerkingen. Ik zou sterk stel voor verder te lezen in LEFT, RIGHT en FULL OUTER JOINs (die samen OUTER JOINs worden genoemd ). Ik heb persoonlijk een kans op een baan gemist omdat ik een keer een zwakke kennis van OUTER JOINs had en zal het niet nog een keer laten gebeuren!

EEN ZELF AANMELDEN is gewoon een JOIN-bewerking waarbij u een tabel aan zichzelf relateert. De manier waarop u ervoor kiest om die tafel naar zichzelf toe te voegen, kan een INNER JOIN . gebruiken of een OUTER JOIN. Merk op dat met een SELF JOIN , om uw SQL-engine niet te verwarren, moet gebruik tabelaliassen (fam en per van hierboven. Verzin wat logisch is voor uw zoekopdracht) of er is geen manier om de verschillende versies te onderscheiden van dezelfde tafel.

Nu je het verschil begrijpt, open je geest lekker breed en realiseer je dat één enkele zoekopdracht alle verschillende soorten JOIN's tegelijk kan bevatten. Het is gewoon een kwestie van welke gegevens u wilt en hoe u uw query moet verdraaien en buigen om deze te krijgen. Als je merkt dat je een zoekopdracht uitvoert en het resultaat van die zoekopdracht neemt en het gebruikt als invoer voor een andere zoekopdracht, dan kun je waarschijnlijk een JOIN gebruiken om er in plaats daarvan één zoekopdracht van te maken.

Als u met SQL wilt spelen, gaat u naar W3Schools.com Er is daar een lokaal opgeslagen database met een aantal tabellen die zijn ontworpen om op verschillende manieren met elkaar in verband te worden gebracht en het is gevuld met gegevens! U kunt CREATE, DROP, INSERT, UPDATE en SELECT alles wat u wilt en de database op elk moment terugzetten naar de standaardwaarde. Probeer allerlei soorten SQL uit om met verschillende trucs te experimenteren. Ik heb daar zelf veel geleerd.

Sorry als dit een beetje omslachtig was, maar ik worstelde persoonlijk met het concept van JOIN's toen ik begon met het leren van SQL en het uitleggen van een concept met behulp van een aantal andere complexe concepten verzandde me. Het is het beste om soms onderaan te beginnen.

Ik hoop dat het helpt. Als je JOIN's in je achterzak kunt stoppen, kun je toveren met SQL!

Veel plezier met zoeken!



  1. Parameters doorgeven aan Oracle SQL-bestand vanuit batchbestand

  2. mysql pivoting - hoe kan ik gegevens uit dezelfde tabel in verschillende kolommen ophalen?

  3. Priemgetallen afdrukken met SQL-query

  4. Stel IGNORECASE en andere opties voor H2 in een Play! Kadertest