Яка різниця між лівими, правими, зовнішніми та внутрішніми приєднаннями?


562

Мені цікаво, як розмежувати всі ці різні приєднання ...



3
Також залежить від рівня вашого розуміння, тому що хтось, як ви, ця стаття не робить нічого, окрім того, хто, можливо, не повністю розуміє, приєднується, це досить зрозуміло
SQLMenace

6
Це дублікат stackoverflow.com/questions/419375/sql-join-differences та без сумніву інших ...
клетус

1
Це мені дуже допомогло ... найпростіший спосіб - скласти тестові таблиці та пограти з ними. = P
daGrevis

Відповіді:


797

Простий приклад . Скажімо, у вас є Studentsтаблиця та Lockersстіл. У SQL перша таблиця, яку ви вказуєте при з'єднанні, Students- це таблиця ВЛЕВО , а друга Lockers, - ПРАВА .

Кожен учень може бути призначений до шафки, тому LockerNumberв Studentтаблиці є стовпець . У одному шафці потенційно може бути більше одного учня, але особливо на початку навчального року у вас можуть бути учні, які надходять, без шаф, а також шафки, яким не призначено учнів.

Заради цього прикладу скажемо, що у вас є 100 учнів , 70 з яких мають шафки. У вас всього 50 шаф , 40 з яких мають щонайменше 1 учня, а 10 шаф не мають студента.

ВНУТРІШНЯ ПРИЄДНАЙТЕ - це " показати мені всіх студентів з шафками ".
Будь-які студенти без шаф або будь-які шафки без учнів відсутні.
Повертає 70 рядів

ЛЕВІШНІЙ ПРИЄДНАЙТЕСЬ було б " покажіть мені всіх студентів із відповідним шафкою, якщо вони мають ".
Це може бути загальний список студентів, або він може бути використаний для ідентифікації студентів, які не мають шафки.
Повертає 100 рядків

ПРАВА ПРИЄДНАЙТЕСЬ ПРИЄДНАЙТЕСЬ буде: " покажи мені всі шафки та учнів, призначених для них, якщо такі є ".
Це може бути використано для виявлення шаф, у яких не призначено студентів, або шаф, у яких занадто багато студентів.
Повертає 80 рядків (список 70 учнів у 40 шафках, плюс 10 шаф без студента)

Повна зовнішня приєднання була б нерозумною і, мабуть, не дуже корисною.
Щось на кшталт " покажіть мені всіх студентів та всі шафки, і підберіть їх там, де ви можете "
Повертає 110 рядків (усі 100 учнів, у тому числі без шаф. Плюс 10 шаф, що не мають студента)

CROSS JOIN також досить глупо в цьому сценарії.
Він не використовує пов'язане lockernumberполе в таблиці студентів, тож ви, в основному, складаєте великий список усіх можливих спарювань «студент до шафки», незалежно від того, чи існує він.
Повертається 5000 рядків (100 учнів х 50 шаф). Може бути корисним (з фільтруванням) як відправна точка для узгодження нових учнів із порожніми шафками.


12
Використовуючи ваш приклад, приєднання до CROSS було б корисно як відправна точка для створення завдань шафки: почніть з усіх можливих комбінацій, а потім використовуйте інші критерії для фільтрації результатів зі списку.
Joel Coehoorn

1
Гарна відповідь. Я вважаю, що Cross Join найчастіше використовується для генерування даних тестування з кількох рядків, коли вам потрібна велика кількість записів.
Елі

6
ПОВНІШНІ ПРИЄДНАННЯ можуть бути корисними при пошуку даних осиротілих або при порівнянні різних версій одного і того ж набору даних.
Лара Дуган

3
Перехресне приєднання, як декартовий продукт
JavaRocky,

3
Я думаю, як ви починаєте запит, впливає на результат типу приєднання. Наприклад, SELECT * FROM students RIGHT OUTER JOIN lockers...це призведе до іншого результату, ніж SELECT * FROM lockers RIGHT OUTER JOIN students.... Відмінна відповідь, але хотілося б побачити його оновленим повним SQLзапитом
jbmilgrom

141

Існує три основні типи приєднання:

  • INNERjoin порівнює дві таблиці і повертає результати лише там, де існує відповідність. Записи з 1-ї таблиці дублюються, коли вони відповідають декільком результатам у 2-й. INNER приєднується, як правило, зменшує набір результатів, але, оскільки записи можна дублювати, це не гарантується.
  • CROSSjoin порівнює дві таблиці і повертає всі можливі комбінації рядків з обох таблиць. Ви можете отримати багато результатів від такого типу приєднання, який може навіть не бути значущим, тому використовуйте з обережністю.
  • OUTERjoin порівнює дві таблиці і повертає дані, коли відповідність доступна або значення NULL в іншому випадку Як і при INNER приєднанні, це буде дублювати рядки в одній таблиці, коли вона збігається з декількома записами в іншій таблиці. OUTER приєднання, як правило, збільшує набір результатів, тому що вони самі не видалять жодного запису з набору. Ви також повинні встановити приєднання OUTER, щоб визначити, коли і куди додати значення NULL:
    • LEFT означає зберігати всі записи з 1-ї таблиці незалежно від того, що і вставляти значення NULL, коли 2-а таблиця не збігається.
    • RIGHT означає навпаки: зберігайте всі записи з 2-ї таблиці незалежно від того, що і вставляти значення NULL, якщо він 1-й таблиці не відповідає.
    • FULL означає зберігати всі записи з обох таблиць і вставляти значення NULL в будь-яку таблицю, якщо немає відповідності.

Часто ви бачите, чи буде OUTERключове слово, опущене з синтаксису. Натомість це буде просто "ВЛІТТЕ ПРИЄДНАЙТЕСЬ", "ПРАВИЛЬНА ПРИЄДНАЙТЕСЬ" або "ПОЛІНЕ ПРИЄДНАЙТЕСЬ". Це робиться тому, що з'єднання INNER та CROSS не мають жодного значення щодо лівого, правого або повного, і тому їх цілком достатньо, щоб однозначно вказати на зовнішнє приєднання.

Ось приклад, коли ви можете використовувати кожен тип:

  • INNER: Ви хочете повернути всі записи з таблиці "Рахунок-фактура" разом з відповідними їм "InvoiceLines". Це передбачає, що кожен дійсний рахунок-фактура матиме принаймні один рядок.
  • OUTER: Ви хочете повернути всі записи "InvoiceLines" для певної рахунки-фактури разом з відповідними записами "InventoryItem". Це бізнес, який також продає послуги, такі, що не всі InvoiceLines матимуть IventoryItem.
  • CROSS: У вас є таблиця цифр з 10 рядками, кожен з яких містить значення '0' до '9'. Ви хочете створити таблицю діапазонів дат, до якої слід приєднатись, щоб у кінцевому підсумку було записано один запис на кожен день у межах діапазону. Завдяки повторному приєднанню цієї таблиці до себе таблиці ви можете створити стільки послідовних цілих чисел, скільки вам потрібно (якщо ви починаєте з 10 до 1-ї потужності, кожен приєднання додає 1 до експонента). Потім скористайтеся функцією DATEADD (), щоб додати ці значення до базової дати для діапазону.

1
Приємно. Я лише додаю, що зазвичай, якщо ви пишете лише "ПРИЄДНАЙТЕСЬ", це означає ВНУТРІШНЕ ПРИЄДНАННЯ
матпоп

47

Існує лише 4 види:

  1. Внутрішня приєднання : найпоширеніший тип. Вихідний рядок створюється для кожної пари вхідних рядків, які відповідають умовам приєднання.
  2. Ліве зовнішнє з'єднання : Те саме, що і внутрішнє з'єднання, за винятком того, що якщо є будь-який рядок, для якого в таблиці праворуч не знайдено відповідного рядка, виводиться рядок, що містить значення з таблиці зліва, причому NULLдля кожного значення в таблиці праворуч. Це означає, що кожен рядок із таблиці зліва з’явиться принаймні один раз у висновку.
  3. Праве зовнішнє з'єднання : Те саме, що і ліве зовнішнє з'єднання, за винятком ролей таблиць, обернених назад.
  4. Повне зовнішнє з'єднання : поєднання лівого та правого зовнішнього з'єднання. Кожен рядок з обох таблиць з’явиться у висновку принаймні один раз.

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

Дякую RusselH за те, що він вказав ПОВНІ приєднання, які я опустив.


1
як щодо повного зовнішнього з'єднання та перехресного з'єднання (декартовий продукт)?
SQLMenace

full - це справді еквівалент двох зовнішніх приєднань
RussellH

25
ПОВНО це те, що ви отримуєте, коли накручуєте внутрішнє з'єднання, і тоді ви задаєте питання "чому я отримую N ^ 2 рядки замість N"? Тоді всі отримують КРЕС на вас.
Пол Томблін

24

Різниця в SQL JOINS:

Дуже просто запам'ятати:

INNER JOIN показувати лише записи, спільні для обох таблиць.

OUTER JOIN весь вміст обох таблиць об'єднаний разом, або вони збігаються, або ні.

LEFT JOIN- це те саме, що LEFT OUTER JOIN- (Виберіть записи з першої (лівішої) таблиці з відповідними записами правої таблиці.)

RIGHT JOINтакий же, як RIGHT OUTER JOIN- (Виберіть записи з другої (найправішої) таблиці з відповідними записами лівої таблиці.)

введіть тут опис зображення


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

9

Перевірте приєднання (SQL) у Вікіпедії

  • Внутрішнє з'єднання - Враховуючи дві таблиці, внутрішнє з'єднання повертає всі рядки, які існують в обох таблицях
  • лівий / правий (зовнішній) приєднання - з огляду на дві таблиці повертає всі рядки, що існують у лівій або правій таблиці вашої спілки, плюс рядки з іншої сторони будуть повернуті, коли стаття приєднання збігається, або нуль буде повернуто для ці стовпці

  • Повна зовнішня - За даними двох таблиць повертає всі рядки і повертає нулі, коли ні лівого, ні правого стовпця немає

  • Перехресні з'єднання - декартові приєднання і можуть бути небезпечними, якщо не використовувати їх обережно


6

Зробити це більш помітним може допомогти. Один приклад:

Таблиця 1:

ID_STUDENT STUDENT_NAME

1               Raony
2               Diogo
3               Eduardo
4               Luiz

Таблиця 2:

ІНДУКЦІОННИЙ ЗАМОК

3               l1
4               l2
5               l3

Що я отримую, коли роблю:

-Inner join of Table 1 and Table 2: 

    - Inner join returns both tables merged only when the key 
      (ID_STUDENT) exists in both tables

    ID_STUDENT       STUDENT_NAME      LOCKER   

        3               Eduardo          l1
        4               Luiz             l2

-Left join of Table 1 and Table 2:

    - Left join merges both tables with all records form table 1, in 
      other words, there might be non-populated fields from table 2

    ID_ESTUDANTE    NOME_ESTUDANTE     LOCKER   

        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2

-Right join of table 1 and table 2:

    - Right join merges both tables with all records from table 2, in 
      other words, there might be non-populated fields from table 1

    ID_STUDENT        STUDENT_NAME     LOCKER   

        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

-Outter join of table 1 and table 2:

    - Returns all records from both tables, in other words, there
      might be non-populated fields either from table 1 or 2.

    ID_STUDENT        STUDENT_NAME     LOCKER   
        1               Raony            -
        2               Diogo            -
        3               Eduardo          l1
        4               Luiz             l2
        5               -                l3

4

LEFT JOINі RIGHT JOINє типами OUTER JOINs.

INNER JOIN є типовим - рядки з обох таблиць повинні відповідати умові приєднання.


5
Я не можу повірити, як ця відповідь має багато відгуків, і водночас вона така неповна.
nbro

Я думаю, це була краща відповідь на початкове запитання.
RussellH

3

Внутрішнє приєднання : Показуйте лише рядки, коли є дані з обох таблиць.

Зовнішнє об'єднання : (вліво / вправо) : Показати весь результат з лівої / правої таблиці з парними рядами ( з ), якщо вона існує , чи ні.


2

Спочатку ви повинні зрозуміти, що робить приєднання? Ми підключаємо кілька таблиць і отримуємо конкретний результат від об'єднаних таблиць. Найпростіший спосіб зробити це з'єднання хрестовини .

Скажімо, таблиця A має два стовпчики A і B. А tableB має три стовпці C і D. Якщо ми застосуємо перехресне з'єднання, це створить багато безглуздих рядків. Тоді нам потрібно зіставити первинний ключ, щоб отримати фактичні дані.

Зліва: він поверне всі записи з лівої таблиці та відповідні записи з правої таблиці.

Праворуч: повернеться навпроти з’єднання зліва. Він поверне всі записи з правої таблиці та відповідні записи з лівої таблиці.

Внутрішня: Це як перехрестя. Він поверне лише відповідні записи з обох таблиць.

Зовнішній: І це як союз. Він поверне всі наявні записи з обох таблиць.

Інколи нам не потрібні всі дані, а також нам потрібні лише загальні дані або записи. ми можемо легко отримати його за допомогою цих методів приєднання. Пам'ятайте, що лівий і правий з'єднання також є зовнішнім з'єднанням.

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

Дякую

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