Яка різниця між ВНУТРІШНЬОМУ ПРИЄДНАННІ І ВНУТРІШНЬОМУ ПРИЄДНАННІ?


35

Я новачок у SQL і хотів дізнатися, в чому різниця між цими двома 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

Коли я повинен використовувати те чи інше?


6
чи підходить це як питання про DBA? Це здається мені кодируючим питанням.
BlackICE

1
@ Розкажіть свої міркування про Meta
Sathyajith Bhat

@David, то VtC, якщо ви думаєте, що це неправильно для сайту. Ми завжди можемо знову відкритись.
jcolebrand

3
Я думаю, що це відмінне запитання і дуже підходить для сайту.
datagod

це потрібно перенести з DBA, якщо нобій DBA не втухнув, щоб налагодити продуктивність БД: P
AmDB

Відповіді:


32
  • Внутрішнє з'єднання буде вибирати тільки запис , де з'єднуються ключі знаходяться в обох зазначених таблицях.
  • Ліві зовнішнє з'єднання буде вибрати всі записи з першої таблиці, а також будь-які записи в другій таблиці , які відповідають приєдналася ключам.
  • Права зовнішнє з'єднання буде вибрати всі записи з другої таблиці, і будь-які записи в першій таблиці , які відповідають приєдналася ключам.

У першому прикладі ви повернете список користувачів та телефонні номери лише у тому випадку, якщо для користувача існує хоча б один запис телефону.

У другому прикладі ви повернете список усіх користувачів, а також будь-які записи телефону, якщо вони доступні (якщо вони недоступні, ви отримаєте NULLзначення телефонних значень).


13

Щоразу, коли хтось задає це запитання, є відповідь: http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Сподіваюся, це допоможе вам зрозуміти,


3
Я працював з приєднаннями 20 років, і ці діаграми мені здавалися заплутаними.
Хоган

3
Я за допомогою діаграм @Hogan - ven не найкраще пояснення цьому .. сітка, яка показує, які комбінації будуть повернуті, швидше за все, буде кращою.
Джо

Все, що показує, це те, що ви не розумієте діаграму Венна. Вони прекрасно відносяться до типів приєднання, але майте на увазі, що вони є інструментом, який допомагає зрозуміти тих, хто починає приєднуватися. Якщо ви вже навчились поєднуватись з іншою концепцією на увазі, то це неодмінно виглядатиме вам. Це не проблема, але це також не є хорошим показником корисності діаграм.
JamesRyan

@jamesryan це неправда, вони не відносяться ідеально, приєднання схожі на декартовий набір множин, а не на перетині та об'єднанні; аналог діаграми venn працює лише в тому випадку, якщо ви приєднуєтесь до унікальних ключів, якщо у вас дублюються ключі, ви втрачаєте декартовий аспект продукту.
Буде чи

1
Я категорично не погоджуюся, що діаграми Венна вже мають дуже чітко виражену інтерпретацію, встановлюють перетин та з'єднання. Приєднання не відповідає цій інтерпретації, коли ви приєднуєтесь до унікальних ключів. Я думаю, ви інтерпретуєте діаграми Венна занадто широко.
Буде

8

Внутрішнє з'єднання повертає рядки , які можуть бути об'єднані на основі приєднатися до критеріям. Зовнішнє з'єднання повертає ці та всі рядки ...    ... з першої таблиці для з'єднання зліва    ... з другої таблиці для з'єднання справа    ... з обох таблиць для повного з'єднання




Вибір, коли використовувати те чи інше, - це питання того, які дані вам потрібні. Для вашого прикладу, якщо вам потрібні лише записи, у яких є user_ids з телефону, які відповідають ідентифікаторам користувача, тоді використовуйте внутрішнє з'єднання. Якщо ви також хочете включити рядки від користувача, які не мають відповідного телефонного входу, ліве з'єднання було б доречним.

Для отримання додаткової інформації дивіться це питання на StackOverflow .


7

Якщо у вас є дві таблиці, як показано нижче:

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

Якщо ви використовуєте Inner Join, ви отримуєте:

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

Якщо ви використовуєте Повне зовнішнє приєднання, ви отримуєте:

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

Якщо ви користуєтеся лівим зовнішнім приєднанням, ви отримуєте:

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

6

Зовнішнє з'єднання явно призначене для створення нульових результатів, тому їх слід уникати взагалі. Якщо говорити відносно, це свого роду шлюб рушниці: він змушує таблиці в своєрідний союз - так, я маю на увазі союз, а не приєднуватися - навіть коли відповідні таблиці не відповідають звичайним вимогам для об'єднання. Це робиться, фактично, доповнивши одну або обидві таблиці нулями перед тим, як зробити об'єднання, тим самим змусивши їх відповідати тим звичайним вимогам. Але немає ніяких причин, чому прокладку не слід робити з належними значеннями замість нулів, як у цьому прикладі:

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

Альтернативно, такий же результат можна отримати, використовуючи оператор зовнішнього з'єднання SQL спільно з COALESCE, як тут:

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

Зауваження про зовнішнє приєднання (4.6) у "SQL та реляційній теорії: як написати точний SQL-код" за CJ Date


5

Внутрішнє з'єднання - це з'єднання, де єдиними результатами відображаються результати, коли ключі знаходяться в обох таблицях. Зовнішнє з'єднання відображатиме результати для всіх клавіш в одній таблиці, ліве з'єднання з першого та праве з'єднання з другого. Наприклад:

Скажімо, таблиця1 має такі пари первинного ключа та даних: (1, a), (2, b), (3, c)

Скажімо також, що таблиця2 має такі пари первинних ключів і даних: (1, весело), ​​(3, може), (4, трапляється)

Отже, внутрішнє з'єднання table1 до table2 на первинних ключах призведе до отримання таких триплетів (із загальним первинним ключем першим, другим елементом першої таблиці та другим елементом другої таблиці): (1, a, fun), ( 3, с, можна)

Ліве зовнішнє з'єднання table1 до table2 на первинних клавішах дасть наступні триплети (такий же формат, що і вище): (1, a, fun), (2, b, NULL), (3, c, can)

Праве зовнішнє з'єднання table1 з table2 на первинних клавішах дасть наступні триплети (такий же формат, як і вище): (1, a, fun), (3, c, can), (4, NULL, буває)

Я сподіваюся, що це пояснює концепцію гідно.


4

Дозвольте спробувати описати це трохи інтуїтивніше.

Внутрішнє з'єднання показує користувачів, які мають один або декілька телефонів разом зі своїми телефонними номерами.

Лівий зовнішній приєднання додатково перераховує тих "користувачів", у яких немає телефону.


4

Оскільки ви запитали, коли використовувати що, ось сценарій із запитами - виберіть, який використовувати, залежно від вимоги.

Дані:

Користувачі таблиці мають 10 записів. Таблиця Phoneno має 6 записів (зі співвідношенням 1: 1, що означає, що запис у PhoneNo посилається лише на один запис у Користувачах, і лише один запис у PhoneNo може посилатися на даний запис у Користувачах).

Вимога 1: Показати всіх користувачів зі своїми номерами телефонів. Ігноруйте користувачів без номера телефону.

Запит:

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

Результат: показує 6 користувачів, які мають номер телефону

Вимога 2: Показати всіх користувачів зі своїм номером телефону. Якщо у користувача немає дисплея телефону "N / A" (недоступно)

Запит:

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

Результат:

Показує всі 10 записів

Примітка: ifnull - синтаксис MySql для перетворення нульового значення. Я використовував цю функцію для того, щоб двигун db показав "N / A", коли phonno є недійсним. Шукайте відповідну функцію, якщо ви використовуєте деякі інші СУБД. У SQL Server ви повинні використовувати CASEоператор.

Я сподіваюся, що це допомагає.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.