it-swarm-eu.dev

Jaký je rozdíl mezi VNITŘNÍM PŘIPOJENÍM a VNĚJŠÍM PŘIPOJENÍM?

Jsem v SQL nový a chtěl vědět, jaký je rozdíl mezi těmito dvěma typy JOIN?

SELECT * 
FROM user u
INNER JOIN telephone t ON t.user_id = u.id

SELECT * 
FROM user u
LEFT OUTER JOIN telephone t ON t.user_id = u.id

Kdy bych měl použít jeden nebo druhý?

35
Julien
  • vnitřní spojení vybere pouze záznamy, kde jsou spojené klíče v obo určených tabulkách.
  • levý vnější spoj vybere všechny záznamy z první tabulky a všechny záznamy v druhé tabulce, které odpovídají spojeným klíčům.
  • pravé vnější spojení vybere všechny záznamy z druhé tabulky a všechny záznamy v první tabulce, které odpovídají spojeným klíčům.

V prvním příkladu vrátíte seznam uživatelů a telefonních čísel pouze v případě, že pro uživatele existuje alespoň jeden telefonní záznam.

Ve druhém příkladu vrátíte seznam uživatelů všichni plus všechny telefonní záznamy, pokud jsou k dispozici (pokud nejsou k dispozici, získáte za telefon NULL) hodnoty).

Kdykoli se někdo zeptá na tuto otázku, existuje odpověď: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Doufám, že vám to pomůže pochopit,

13
Spredzy

vnitřní spojení vrací řádky, které lze kombinovat na základě kritérií spojení.
vnější spojení vrátí tyto a všechny řádky ...
... z první tabulky pro spojení vlevo
... z druhé tabulky pro pravé spojení
... z obou tabulek pro úplné připojení

Výběr toho, kdy použít jedno nebo druhé, je otázkou určení, jaká data potřebujete. Pro příklad, pokud potřebujete pouze záznamy, které mají user_ids z telefonu, které odpovídají ID v uživateli, pak použijte vnitřní spojení. Pokud chcete také zahrnout řádky od uživatele, kteří nemají odpovídající telefonní záznam, pak by bylo vhodné levý spoj.

Více informací viz tato otázka na StackOverflow .

8
Leigh Riffel

Pokud máte 2 tabulky jako níže:

Table1 :   A1    B1          Table2  :    B2     C2 
           -     -                        -      -
           1     2                        1      1
           2     4                        2      4
           3     5                        5      2

Pokud používáte Inner Join, získáte:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2

Pokud používáte Full Outer Join, získáte:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
NULL   NULL    1       1

Pokud používáte Left Outer Join, získáte:

 A1     B1     B2      C2  
 -      -      -       -
 1      2      2       4
 3      5      5       2
 2      4    NULL     NULL
7
Am1rr3zA

Vnější spojení je výslovně navrženo tak, aby ve výsledku mělo nulové hodnoty, a proto by se mu obecně nemělo vyhýbat. Relativně řečeno, jedná se o jakýsi brokovnický sňatek: nutí tabulky do jakési unie - ano, mám na mysli unii, ne připojení - i když dotyčné tabulky nesplňují obvyklé požadavky na spojení. Dělá to ve skutečnosti tím, že před provedením sjednocení vyloží jednu nebo obě tabulky na null, čímž se nakonec nakonec shodují s těmito obvyklými požadavky. Neexistuje však žádný důvod, proč by se toto vycpání nemělo provádět se správnými hodnotami namísto nulových hodnot, jako v tomto příkladu:

SELECT SNO , PNO 
FROM   SP 
UNION  
SELECT SNO , 'nil' AS PNO 
FROM   S 
WHERE  SNO NOT IN ( SELECT SNO FROM SP )

Alternativně by stejný výsledek mohl být získán použitím operátoru vnějšího spojení SQL ve spojení s COALESCE, jak zde:

SELECT SNO , COALESCE ( PNO , 'nil' ) AS PNO 
FROM ( S NATURAL LEFT OUTER JOIN SP ) AS TEMP

Poznámka k vnějšímu spojení (4.6) v kapitole „SQL a relační teorie: Jak napsat přesný kód SQL“ do C.J. Date

6
onedaywhen

Vnitřní spojení je spojení, kde jsou zobrazeny pouze výsledky, kde jsou klíče v obou tabulkách. Vnější spojení zobrazí výsledky pro všechny klíče v jedné tabulce, levé spojení od prvního a pravé spojení od druhého. Například:

Řekněme, že tabulka1 má následující páry primárních klíčů a dat: (1, a), (2, b), (3, c)

Řekněme také, že tabulka2 má následující páry primárních klíčů a dat: (1, zábava), (3, může), (4, stane se)

Takže vnitřní spojení tabulky 1 s tabulkou 2 na primárních klíčích by přineslo následující výsledná trojčata (s prvním společným primárním klíčem, druhou položkou první tabulky druhé a druhou položkou druhé tabulky třetí): (1, a, zábava), ( 3, c, plechovka)

Levé vnější spojení tabulky1 s tabulkou2 na primárních klíčích by poskytlo následující výsledné triplety (stejný formát jako výše): (1, a, fun), (2, b, NULL), (3, c, can)

Správné vnější spojení tabulky1 s tabulkou2 na primárních klíčích by poskytlo následující výsledné triplety (stejný formát jako výše): (1, a, zábava), (3, c, může), (4, NULL, stane se)

Doufám, že to vysvětlí tento koncept slušně.

5
indyK1ng

Protože jste se zeptali, kdy použít co, zde je scénář s dotazy - vyberte, které chcete použít v závislosti na požadavku.

Data:

Uživatelé tabulky mají 10 záznamů. Tabulka Phoneno má 6 záznamů (s relací 1: 1, což znamená, že položka v PhoneNo bude odkazovat pouze na jeden záznam v Uživateli a pouze jeden záznam v PhoneNo může odkazovat na daný záznam v Uživatelé).

Požadavek 1: Zobrazit všem uživatelům jejich telefonní čísla. Ignorovat uživatele bez telefonního čísla.

Dotaz:

SELECT u.uid, u.name, p.phonno 
  FROM user u 
INNER JOIN phones p ON p.uid = u.uid

Výsledek: zobrazuje 6 uživatelů, kteří mají telefonní číslo

Požadavek 2: Zobrazit všem uživatelům své telefonní číslo. Pokud uživatel nemá telefonní displej „N/A“ (není k dispozici)

Dotaz:

SELECT u.uid, u.name, ifnull(p.phonno,'N/A') 
  FROM user u 
LEFT OUTER JOIN phones p ON p.uid = u.uid

Výsledek:

Zobrazí všech 10 záznamů

Poznámka: ifnull je syntaxe MySql pro transformaci hodnoty null. Tuto funkci jsem použil k tomu, aby db engine ukazoval 'N/A', když je fonno null. Vyhledejte vhodnou funkci, pokud používáte jiné DBMS. V SQL Serveru musíte použít příkaz CASE.

Doufám, že to pomůže.

4
AmDB

Zkusím to popsat trochu intuitivněji.

Vnitřní spojení zobrazuje uživatele, kteří mají jeden nebo více telefonů spolu s jejich telefonními čísly.

Vlevo se připojují další uživatelé, kteří nemají telefon.

4
bernd_k