sql >> Databasteknik >  >> RDS >> Oracle

självfoga vs inre sammanfogning

Jag tycker att det är bra att tänka på alla tabeller i en SELECT-sats som representerar deras egna datamängder.

Innan du har tillämpat några villkor kan du tänka dig att varje datamängd är komplett (till exempel hela tabellen).

En koppling är bara ett av flera sätt att börja förfina dessa datamängder för att hitta den information du verkligen vill ha.

Även om ett databasschema kan utformas med vissa relationer i åtanke (Primärnyckel <-> Utländsk nyckel) existerar dessa relationer egentligen bara i samband med en viss fråga. Frågeskrivaren kan relatera vad de vill till vad de vill. Jag ska ge ett exempel på detta senare...

En INNER JOIN kopplar två tabeller till varandra. Det finns ofta flera JOIN-operationer i en fråga för att kedja ihop flera tabeller. Det kan bli hur komplicerat som helst. För ett enkelt exempel, överväg följande tre tabeller...

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

STUDENT-tabellen och CLASS-tabellen designades för att relatera till varandra genom ENROLLMENT-tabellen. Den här typen av tabell kallas Junction Table .

För att skriva en fråga för att visa alla elever och de klasser de är inskrivna i skulle man använda två inre skarvar...

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;

Läs ovanstående noga så bör du se vad som händer. Vad du får tillbaka är följande datamängd...

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

Genom att använda JOIN-klausulerna har vi begränsat datamängderna för alla tre tabellerna till endast de som matchar varandra. "Träffningarna" definieras med ON klausuler. Observera att om du körde den här frågan skulle du inte se CLASSID 4-raden från CLASS-tabellen eller STUDENTID 1-raden från STUDENT-tabellen eftersom dessa ID:n inte finns i matchningarna (i det här fallet ENROLLMENT-tabellen). Titta på "LEFT"/"RIGHT"/"FULL OUTER" JOINs för mer läsning om hur du får det att fungera lite annorlunda.

Observera att det enligt mina kommentarer om "relationer" tidigare finns ingen anledning varför du inte kunde köra en fråga som relaterade till STUDENT-tabellen och CLASS-tabellen direkt på kolumnerna LASTNAME och PROFESSOR. De två kolumnerna matchar i datatyp och titta på det! De har till och med ett värde gemensamt! Detta skulle förmodligen vara en konstig datamängd att få tillbaka. Min poäng är att det kan göras och du vet aldrig vilka behov du kan ha i framtiden för intressanta kopplingar i din data. Förstå utformningen av databasen men tänk inte på "relationer" som regler som inte kan ignoreras.

Under tiden... GÅR SJÄLV MED!

Tänk på följande tabell...

PERSON

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

Om du kände dig så benägen att skapa en databas över alla människor du känner och vilka som tillhör samma familj kan det vara så det ser ut.

Om du vill lämna tillbaka en person, till exempel PERSONID 4, skulle du skriva...

SELECT * FROM PERSON WHERE PERSONID = 4;

Du skulle få veta att han är i familjen med FAMILYID 2. För att sedan hitta alla av PERSONerna i hans familj skulle du skriva...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Klart och gjort! SQL kan naturligtvis åstadkomma detta i en fråga med, du gissade rätt, en SELF JOIN.

Det som verkligen utlöser behovet av en JÄLVGÅNG här är att tabellen innehåller en unik kolumn (PERSONID) och en kolumn som fungerar som en sorts "Kategori" (FAMILYID). Detta koncept kallas Kardinalitet och representerar i det här fallet en ett till många eller 1:M relation. Det finns bara en för varje PERSON men det finns många PERSONER i en FAMILJ .

Så det vi vill ge tillbaka är allt av medlemmarna i en familj om en medlem av familjens PERSONID är känd...

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

Här är vad du skulle få...

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

Låt oss notera ett par saker. Orden SJÄLV GÅ MED förekommer inte någonstans. Det beror på att en SJÄLVGÅR MED är bara ett koncept. Ordet GÅ MED i frågan ovan kunde ha varit en LEFT JOIN istället och andra saker skulle ha hänt. Poängen med en SJÄLVGÅNG är att du använder samma tabell två gånger.

Tänk på min tvållåda från tidigare på datamängder. Här har vi börjat med datamängden från PERSON-tabellen två gånger. Varken instansen av datamängden påverkar den andra om vi inte säger att den gör det.

Låt oss börja längst ner i frågan. per datauppsättningen begränsas till endast de rader där PERSONID =4. Vi känner till tabellen som kommer att returnera exakt en rad. Kolumnen FAMILYID i den raden har värdet 2.

I ON-klausulen begränsar vi fam datauppsättning (som vid denna tidpunkt fortfarande är hela PERSON-tabellen) till endast de rader där värdet på FAMILYID matchar en eller flera av FAMILYIDerna för per datauppsättning. Som vi diskuterade känner vi till per datamängden har bara en rad, därför ett FAMILYID-värde. Därför familjen datauppsättningen innehåller nu bara rader där FAMILYID =2.

Slutligen, längst upp i frågan väljer vi alla rader i fam datauppsättning.

Voila! Två frågor i en.

Sammanfattningsvis en INRE JOIN är en av flera typer av JOIN-verksamhet. Jag skulle starkt föreslå att du läser vidare i LEFT, RIGHT och FULL OUTER JOINs (som tillsammans kallas OUTER JOINs ). Jag har personligen missat ett jobbtillfälle för att ha en svag kunskap om OUTER JOINs en gång och kommer inte låta det hända igen!

EN SJÄLV GÅ MED är helt enkelt vilken JOIN-operation som helst där du relaterar en tabell till sig själv. Sättet du väljer att JOIN den tabellen till sig själv kan använda en INNER JOIN eller en OUTTER JOIN. Observera att med en SJÄLV GÅ MED , för att inte förvirra din SQL-motor du måste använd tabellalias (fam och per från ovan. Gör vad som är vettigt för din fråga) eller så finns det inget sätt att skilja de olika versionerna i samma tabell.

Nu när du förstår skillnaden öppna ditt sinne snällt och inse att en enda fråga kan innehålla alla olika typer av JOINs på en gång. Det är bara en fråga om vilken data du vill ha och hur du måste vrida och böja din fråga för att få den. Om du kommer på att du kör en fråga och tar resultatet av den frågan och använder den som indata för en annan fråga kan du förmodligen använda en JOIN för att göra det till en fråga istället.

För att leka med SQL prova att besöka W3Schools.com Det finns en lokalt lagrad databas där med ett gäng tabeller som är designade för att relatera till varandra på olika sätt och den är fylld med data! Du kan SKAPA, SLIPPA, INFOGA, UPPDATERA och VÄLJA allt du vill och återställa databasen till dess standard när som helst. Prova alla sorters SQL för att experimentera med olika knep. Jag har själv lärt mig mycket där.

Ursäkta om det här var lite ordigt men jag kämpade personligen med konceptet JOINs när jag började lära mig SQL och förklara ett koncept genom att använda en massa andra komplexa koncept gjorde mig fast. Bäst att börja på botten ibland.

Jag hoppas att det hjälper. Om du kan lägga JOINs i bakfickan kan du arbeta magi med SQL!

Lycka till med att fråga!



  1. Skapa dynamiskt kolumner sql

  2. MySql spanska teckendata

  3. Hur OCT()-funktionen fungerar i MySQL

  4. MySQL Performance – 5 parametrar från konfigurationsfilen