sql >> Databasteknik >  >> RDS >> Oracle

Vänster och höger sammanfogar med hjälp av plustecknet (+) i Oracle

  • Vad är en Inner Join?
  • Vad är en Outer Join?
    • Utföra yttre sammanfogningar med hjälp av (+)-symbolen

Liksom praktiskt taget alla relationsdatabaser tillåter Oracle att frågor genereras som kombinerar eller JOIN rader från två eller flera tabeller för att skapa den slutliga resultatuppsättningen. Även om det finns många typer av joins som kan utföras är de vanligaste INNER JOIN och OUTER JOIN .

I den här handledningen ska vi kort utforska skillnaden mellan INNER och OUTER JOIN och undersök sedan förkortningsmetoden Oracle tillhandahåller för att utföra OUTER JOINS specifikt med hjälp av + operatörssymbol.

Vad är en Inner Join?

En INNER JOIN i en relationsdatabas är helt enkelt sammanfogningen av två eller flera tabeller där resultatet endast kommer att innehålla data som uppfyller alla sammanfogningsvillkor .

Till exempel, här har vi ett grundläggande library schema med två tabeller:books och languages . languages tabellen är bara en lista över möjliga språknamn och ett unikt språk id :

SELECT * FROM library.languages;

id   name
1   English
2   French
3   German
4   Mandarin
5   Spanish
6   Arabic
7   Japanese
8   Russian
9   Greek
10   Italian

Under tiden våra books tabellen har ett language_id rad som för de flesta, men inte alla, böcker helt enkelt innehåller language_id kopplat till bokens originalspråk:

SELECT * FROM
  books
ORDER BY
  id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language_id
1   In Search of Lost Time  Marcel Proust   1913    2
2   Ulysses James Joyce 1922    1
3   Don Quixote Miguel de Cervantes 1605    5
4   Moby Dick   Herman Melville 1851    1
5   Hamlet  William Shakespeare 1601 (null)
6   War and Peace   Leo Tolstoy 1869    8
7   The Odyssey Homer   -700    9
8   The Great Gatsby    F. Scott Fitzgerald 1925    1
9   The Divine Comedy   Dante Alighieri     1472    10
10  Madame Bovary   Gustave Flaubert    1857    2

I många fall kanske vi vill utföra en INNER JOIN av books och languages tabeller så istället för att se det meningslösa language_id värdet av varje bok kan vi faktiskt se language name istället.

SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b
INNER JOIN
  library.languages l
ON
  b.language_id = l.id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language
1   In Search of Lost Time  Marcel Proust   1913    French
2   Ulysses James Joyce 1922    English
3   Don Quixote Miguel de Cervantes 1605    Spanish
4   Moby Dick   Herman Melville 1851    English
6   War and Peace   Leo Tolstoy 1869    Russian
7   The Odyssey Homer   -700    Greek
8   The Great Gatsby    F. Scott Fitzgerald 1925    English
9   The Divine Comedy   Dante Alighieri     1472    Italian
10  Madame Bovary   Gustave Flaubert    1857    French
11  The Brothers Karamazov  Fyodor Dostoyevsky  1880    Russian

Det som är viktigt att notera här är att vår resultatuppsättning var något annorlunda i de två ovanstående frågorna. I den första listade vi helt enkelt de första 10 böcker, men i INNER JOIN fråga returnerar vi bara resultat som uppfyller alla villkor från båda tabellerna. Av denna anledning, posten för Hamlet (som har ett language_id värdet på null eller tom) ignoreras och returneras inte i resultatet av vår INNER JOIN .

Vad är en Outer Join?

Istället för att endast returnera resultat som uppfyller alla anslutningsvillkor för en INNER JOIN , en OUTER JOIN ger inte bara resultat som uppfyller alla villkor, utan även returnerar rader från en tabell som inte uppfyllde villkoret. Tabellen som väljs för denna "bypass" av villkorliga krav bestäms av riktningen eller "sidan" av kopplingen, vanligtvis kallad LEFT eller RIGHT yttre sammanfogningar.

När du definierar en sida till din OUTER JOIN , anger du vilken tabell som alltid ska returnera sin rad även om den motstående tabellen på andra sidan av kopplingen saknas eller null värden som en del av sammanfogningsvillkoret.

Därför, om vi utför samma grundläggande JOIN som ovan för att hämta books och language names , vi vet att våra books Tabellen ska alltid returnera data, så vår JOIN sidan ska "peka mot" våra books tabell, vilket gör languages tabell OUTER bord vi fäster vid den.

För att åstadkomma detta ändrar vi helt enkelt:

books b INNER JOIN library.languages l

…till detta:

books b LEFT OUTER JOIN library.languages l

Således ser hela fråge- och resultatuppsättningen nästan identisk ut med INNER JOIN förutom den mindre ändringen:

SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b
LEFT OUTER JOIN
  library.languages l
ON
  b.language_id = l.id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

id title    author    year_published    language
1   In Search of Lost Time  Marcel Proust   1913    French
2   Ulysses James Joyce 1922    English
3   Don Quixote Miguel de Cervantes 1605    Spanish
4   Moby Dick   Herman Melville 1851    English
5   Hamlet  William Shakespeare 1601  (null)
6   War and Peace   Leo Tolstoy 1869    Russian
7   The Odyssey Homer   -700    Greek
8   The Great Gatsby    F. Scott Fitzgerald 1925    English
9   The Divine Comedy   Dante Alighieri     1472    Italian
10  Madame Bovary   Gustave Flaubert    1857    French

Som förväntat, genom att använda en LEFT OUTER JOIN istället för föregående INNER JOIN , vi får det bästa av två världar:Vi hoppar inte över några books poster (som Hamlet ) helt enkelt för att language_id värdet är null för den posten, men för alla poster där language_id existerar får vi det snyggt formaterade language name hämtat från våra languages bord.

Utföra yttre sammanfogningar med hjälp av (+)-symbolen

Som anges i den officiella dokumentationen tillhandahåller Oracle en speciell outer join operator (+ symbol) som är en förkortning för att utföra OUTER JOINS .

I praktiken är + symbolen placeras direkt i den villkorliga uttalande och på sidan av den valfria tabellen (den som får innehålla tom eller null värden inom det villkorliga).

Därför kan vi återigen skriva om vår LEFT OUTER JOIN ovan uttalande med + operatör som så:

SELECT
  b.id,
  b.title,
  b.author,
  b.year_published,
  l.name language
FROM
  books b,
  library.languages l
WHERE
  l.id (+)= b.language_id
ORDER BY
  b.id
FETCH FIRST 10 ROWS ONLY;

Resultaten är desamma som standard LEFT OUTER JOIN exemplet ovan, så vi tar inte med dem här. Det finns dock en viktig aspekt att lägga märke till om syntaxen med + operator för OUTER JOINS .

+ operatör måste vara på vänster sida av det villkorliga (vänster om är lika med = tecken). Därför, i det här fallet, eftersom vi vill säkerställa att våra languages table är den valfria tabellen som kan returnera null värden under den här jämförelsen bytte vi tabellernas ordning i detta villkorliga, så languages är till vänster (och är valfritt) medan books är till höger.

Slutligen, på grund av denna omordning av tabellsidorna i villkoret när du använder + operatör är det viktigt att inse att ovanstående bara är en förkortning för en RIGHT OUTER JOIN . Detta betyder att detta utdrag av frågan:

FROM
  books b,
  library.languages l
WHERE
  l.id (+)= b.language_id

…är faktiskt identisk med detta:

FROM
  library.languages l
RIGHT OUTER JOIN
  books b
ON
  b.language_id = l.id

  1. Hibernate Långsam för att få Postgres-anslutning

  2. Access-kompatibel Wide World Importers SQL Server Database

  3. Bästa sättet att kontrollera om mysql_query gav några resultat?

  4. Få första veckodagen i SQL Server