sql >> Databáze >  >> RDS >> Oracle

vlastní spojení vs vnitřní spojení

Považuji za užitečné myslet si, že všechny tabulky v příkazu SELECT představují jejich vlastní datové sady.

Než použijete jakékoli podmínky, můžete každý soubor dat považovat za úplný (například celou tabulku).

Spojení je jen jedním z několika způsobů, jak začít zpřesňovat tyto datové sady, abyste našli informace, které opravdu chcete.

Ačkoli schéma databáze může být navrženo s ohledem na určité vztahy (primární klíč <-> cizí klíč), tyto vztahy skutečně existují pouze v kontextu konkrétního dotazu. Pisatel dotazu může vztahovat, co chce, s čímkoli. Později uvedu příklad...

INNER JOIN spojuje dvě tabulky navzájem. V jednom dotazu se často vyskytuje více operací JOIN pro zřetězení více tabulek. Může se to zkomplikovat, jak je potřeba. Pro jednoduchý příklad zvažte následující tři tabulky...

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

Tabulka STUDENT a tabulka CLASS byly navrženy tak, aby se vzájemně vztahovaly prostřednictvím tabulky ZÁPIS. Tento druh tabulky se nazývá Junction Table .

Chcete-li napsat dotaz pro zobrazení všech studentů a tříd, do kterých jsou zapsáni, použijte dva vnitřní spoje...

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;

Přečtěte si pozorně výše uvedené a měli byste vidět, co se děje. Na oplátku získáte následující soubor dat...

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

Pomocí klauzulí JOIN jsme omezili datové sady všech tří tabulek pouze na ty, které si navzájem odpovídají. "Shody" jsou definovány pomocí ZAP doložky. Všimněte si, že pokud byste spustili tento dotaz, nebyli viz řádek CLASSID 4 z tabulky CLASS nebo řádek STUDENTID 1 z tabulky STUDENT, protože tato ID ve shodách neexistují (v tomto případě tabulka EROLLMENT). Podívejte se do "LEFT"/"RIGHT"/"FULL OUTER" JOIN, kde najdete další informace o tom, jak to udělat trochu jinak.

Vezměte prosím na vědomí, že podle mých předchozích komentářů k „vztahům“ neexistuje žádný důvod proč jste nemohli spustit dotaz týkající se tabulky STUDENT a tabulky CLASS přímo ve sloupcích LASTNAME a PROFESSOR. Tyto dva sloupce se shodují v datovém typu a podívejte se na to! Mají dokonce společnou hodnotu! Pravděpodobně by to byla podivná datová sada, kterou lze získat na oplátku. Jde mi o to, že to lze udělat a nikdy nevíte, jaké budete v budoucnu potřebovat zajímavá spojení ve vašich datech. Pochopte návrh databáze, ale nepovažujte „vztahy“ za pravidla, která nelze ignorovat.

Mezitím... SE PŘIPOJÍME!

Zvažte následující tabulku...

PERSON

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

Pokud byste měli takovou chuť vytvořit databázi všech lidí, které znáte a kteří jsou ve stejné rodině, mohlo by to vypadat takto.

Pokud byste chtěli vrátit jednu osobu, například OSOBU 4, napište...

SELECT * FROM PERSON WHERE PERSONID = 4;

Dozvěděli byste se, že je v rodině s FAMILYID 2. Pak najít vše z OSOB v jeho rodině byste napsal...

SELECT * FROM PERSON WHERE FAMILYID = 2;

Hotovo a hotovo! SQL to samozřejmě dokáže v jednom dotazu pomocí, uhodli jste, SELF JOIN.

Co skutečně spouští potřebu SELF JOIN zde tabulka obsahuje jedinečný sloupec (PERSONID) a sloupec, který slouží jako druh "kategorie" (FAMILYID). Tento koncept se nazývá kardinalita a v tomto případě představuje jedna k mnoha nebo 1:M vztah. Existuje pouze jeden každého PERSON ale je jich mnoho PERSON v RODINĚ .

Takže to, co chceme vrátit, je vše členů rodiny, pokud jeden PERSONID člena rodiny je znám...

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

Zde je to, co byste získali...

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

Všimněme si několika věcí. Slova SELF JOIN se nikde nevyskytují. Je to proto, že SELF PŘIPOJENÍ je jen koncept. Slovo JOIN ve výše uvedeném dotazu mohlo být LEFT JOIN místo toho by se staly jiné věci. Smysl SELF JOIN je, že stejnou tabulku používáte dvakrát.

Zvažte můj mýdlový box z dřívějška na souborech dat. Zde jsme začali s datovým souborem z tabulky PERSON dvakrát. Ani instance datové sady ovlivňuje druhou, pokud neřekneme, že ano.

Začněme ve spodní části dotazu. za datová sada je omezena pouze na ty řádky, kde PERSONID =4. Když známe tabulku, víme, že vrátí přesně jeden řádek. Sloupec FAMILYID v tomto řádku má hodnotu 2.

V klauzuli ON omezujeme fam datovou sadu (což je v tuto chvíli stále celá tabulka PERSON) pouze na ty řádky, kde hodnota FAMILYID odpovídá jedné nebo více z FAMILYID z za datový soubor. Jak jsme diskutovali, známe per datová sada má pouze jeden řádek, tedy jednu hodnotu FAMILYID. Proto fam datová sada nyní obsahuje pouze řádky, kde FAMILYID =2.

Nakonec v horní části dotazu VYBERÁME všechny řádky v fam soubor dat.

Voila! Dva dotazy v jednom.

Na závěr INNER JOIN je jedním z několika druhů operací JOIN. Já bych silně doporučujeme číst dále do LEFT, RIGHT a FULL OUTER JOINs (které se souhrnně nazývají OUTER JOINs ). Osobně jsem promeškal pracovní příležitost, protože jsem jednou měl slabé znalosti o OUTER JOINs a nedovolím, aby se to opakovalo!

VLASTNÍ PŘIPOJENÍ je prostě jakákoli operace JOIN, kde propojujete stůl sám se sebou. Způsob, jakým se rozhodnete připojit k tomuto stolu, může použít INNER JOIN nebo OUTER JOIN. Všimněte si, že pomocí SELF JOIN , abyste si nepletli svůj SQL engine, který musíte použijte aliasy tabulek (fam a per shora. Vymyslete, co dává vašemu dotazu smysl) nebo neexistuje způsob, jak odlišit různé verze stejné tabulky.

Nyní, když chápete rozdíl, otevřete svou mysl hezky a široce a uvědomte si, že jeden jediný dotaz může obsahovat všechny různé druhy JOINů najednou. Jde jen o to, jaká data chcete a jak musíte svůj dotaz zkroutit a ohnout, abyste je získali. Pokud zjistíte, že spouštíte jeden dotaz a berete výsledek tohoto dotazu a používáte jej jako vstup dalšího dotazu, pravděpodobně můžete použít JOIN aby to byl jeden dotaz.

Chcete-li si pohrát s SQL, zkuste navštívit W3Schools.com Je tam lokálně uložená databáze s hromadou tabulek, které jsou navrženy tak, aby na sebe různě navazovaly, a je plná dat! Můžete VYTVOŘIT, DROP, INSERT, AKTUALIZOVAT a VYBRAT vše, co chcete, a kdykoli vrátit databázi zpět do výchozího stavu. Vyzkoušejte všechny druhy SQL a experimentujte s různými triky. Sám jsem se tam hodně naučil.

Omlouvám se, jestli to bylo trochu rozvláčné, ale já osobně jsem se potýkal s konceptem JOINů, když jsem se začínal učit SQL a vysvětlování konceptu pomocí spousty dalších složitých konceptů mě zarazilo. Nejlepší je někdy začít odspodu.

Doufám, že to pomůže. Pokud si můžete dát JOINy ​​do zadní kapsy, můžete kouzlit s SQL!

Příjemné dotazování!



  1. MariaDB JSON_MERGE_PRESERVE() Vysvětleno

  2. Převod řetězce s oddělovači na více hodnot v mysql

  3. načíst poslední vložený řádek od každého uživatele v databázi

  4. Naplňte databázi Django