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


85

Яка різниця між INNER JOINі LEFT SEMI JOIN?

Чому в наведеному нижче сценарії я отримую два різні результати?

Набір INNER JOINрезультатів набагато більший. Хтось може пояснити? Я намагаюся отримати імена, table_1що містяться лише в table_2.

SELECT name
FROM table_1 a
    INNER JOIN table_2 b ON a.name=b.name

SELECT name
FROM table_1 a
    LEFT SEMI JOIN table_2 b ON (a.name=b.name)

2
Внутрішнє приєднання досягне вашої мети. Я ніколи не чув про напівприєднання, поки не побачив цього питання.
Dan Bracuk,

left semi joinПовинен повертатися більше рядків , ніж inner join.
Гордон Лінофф

1
inner joinПовертатиме дані тільки якщо є відповідність між двома таблицями. left joinПовертатиме дані з першої таблиці , незалежно , якщо знайдена відповідна запис в другій таблиці.
j03z

11
@GordonLinoff не обов'язково, а LEFT SEMI JOINповерне лише один рядок зліва, навіть якщо праворуч є кілька збігів. Ан INNER JOINповерне кілька рядків, якщо праворуч є декілька відповідностей.
D Stanley

1
@ j03z, що не може бути правильним. Якщо метою лівого hemi-join є 1) повернути лише інформацію в лівій таблиці (як сказали інші) та 2) повернути рядки з лівої таблиці незалежно від збігу (як я думаю, що ви кажете), тоді це лише оригінальна ліва таблиця - для цього не потрібне приєднання. Я думаю, інші мають бути правильними, що лівий hemi-join 1) повертає лише стовпці з лівої таблиці, 2) повертає лише рядки, які мають відповідність у правій таблиці, і 3) поверне один рядок зліва на один або більше матчів.
Carl G

Відповіді:


127

INNER JOINМоже повертати дані зі стовпців з обох таблиць, і може дублювати значення записів по обидві сторони мають більш ніж один матч. A LEFT SEMI JOINможе повертати лише стовпці з лівої таблиці і видає один із кожного запису з лівої таблиці, де в правій таблиці є одне або кілька збігів (незалежно від кількості збігів). Це еквівалентно (у стандартному SQL):

SELECT name
FROM table_1 a
WHERE EXISTS(
    SELECT * FROM table_2 b WHERE (a.name=b.name))

Якщо в правому стовпці є кілька відповідних рядків, a INNER JOINповерне по одному рядку для кожного збігу в правій таблиці, тоді як a LEFT SEMI JOINповертає лише рядки з лівої таблиці, незалежно від кількості відповідних рядків з правого боку. Ось чому ви бачите різну кількість рядків у своєму результаті.

Я намагаюся отримати імена в table_1, які відображаються лише в table_2.

Тоді a LEFT SEMI JOIN- відповідний запит для використання.


Чи справді існує таке поняття як LEFT SEMI JOIN? Хіба не просто SEMI JOIN? Немає сенсу RIGHT SEMI JOIN, правда?
ErikE

У Вулику , так.
D Stanley

1
чудова відповідь саме те, що я шукав. я б сформулював відповідь точніше: "... ВНУТРІШНЄ ПРИЄДНАННЯ поверне один рядок для кожного відповідного рядка правої таблиці , тоді як
ЛІВО НАПІВСЬКЕ ПРИЄДНАННЯ

2
Навпаки цьому є ЛІВА АНТИПРИЄДНАННЯ, яка фільтрує дані з правої таблиці в лівій таблиці відповідно до ключа. Думав, я залишу цей самородок тут для когось, хто може шукати!
shantanusinghal

65

Припустимо, є 2 таблиці TableA та TableB з лише 2 стовпцями (Id, Data) та такими даними:

Таблиця A:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataA11 |
|  1 | DataA12 |
|  1 | DataA13 |
|  2 | DataA21 |
|  3 | DataA31 |
+----+---------+

Таблиця B:

+----+---------+
| Id |  Data   |
+----+---------+
|  1 | DataB11 |
|  2 | DataB21 |
|  2 | DataB22 |
|  2 | DataB23 |
|  4 | DataB41 |
+----+---------+

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

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
'----'---------'----'---------'

Ліве приєднання (або ліве зовнішнє приєднання) у стовпці Idповерне стовпці як з таблиць, так і відповідні записи із записами з лівої таблиці (нульові значення з правої таблиці):

.----.---------.----.---------.
| Id |  Data   | Id |  Data   |
:----+---------+----+---------:
|  1 | DataA11 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA12 |  1 | DataB11 |
:----+---------+----+---------:
|  1 | DataA13 |  1 | DataB11 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB21 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB22 |
:----+---------+----+---------:
|  2 | DataA21 |  2 | DataB23 |
:----+---------+----+---------:
|  3 | DataA31 |    |         |
'----'---------'----'---------'

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

┌────┬─────────┬────┬─────────┐
│ Id │  Data   │ Id │  Data   │
├────┼─────────┼────┼─────────┤
│  1 │ DataA11 │  1 │ DataB11 │
│  1 │ DataA12 │  1 │ DataB11 │
│  1 │ DataA13 │  1 │ DataB11 │
│  2 │ DataA21 │  2 │ DataB21 │
│  2 │ DataA21 │  2 │ DataB22 │
│  2 │ DataA21 │  2 │ DataB23 │
│    │         │  4 │ DataB41 │
└────┴─────────┴────┴─────────┘

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

╔════╦═════════╦════╦═════════╗
║ Id ║  Data   ║ Id ║  Data   ║
╠════╬═════════╬════╬═════════╣
║  - ║         ║    ║         ║
║  1 ║ DataA11 ║  1 ║ DataB11 ║
║  1 ║ DataA12 ║  1 ║ DataB11 ║
║  1 ║ DataA13 ║  1 ║ DataB11 ║
║  2 ║ DataA21 ║  2 ║ DataB21 ║
║  2 ║ DataA21 ║  2 ║ DataB22 ║
║  2 ║ DataA21 ║  2 ║ DataB23 ║
║  3 ║ DataA31 ║    ║         ║
║    ║         ║  4 ║ DataB41 ║
╚════╩═════════╩════╩═════════╝

Ліве напівприєднання до стовпця Idповерне стовпці лише з лівої таблиці та відповідні записи лише з лівої таблиці:

┌────┬─────────┐
│ Id │  Data   │
├────┼─────────┤
│  1 │ DataA11 │
│  1 │ DataA12 │
│  1 │ DataA13 │
│  2 │ DataA21 │
└────┴─────────┘

Раніше я називав це як "LEFT INNER Join".
Аншул Джоші

DISTINCT від A. * від результату INNER JOIN еквівалентно LEFT SEMI JOIN.
Тея

4
Виразний звучить не безпечно, припустимо, що А містить два однакові записи.
Денніс Джахеруддін

Навіть якщо результат виявиться однаковим, використання DISTINCT може мати дорожчий план порівняно з EXISTS
manotheshark

32

Спробував у Вулику і отримав нижченаведений результат

таблиця1

1, wqe, Ченнаї, Індія

2, сту, Салем, Індія

3, Міа, Бангалор, Індія

4, Yepie, Нью-Йорк, США

таблиця2

1, wqe, Ченнаї, Індія

2, сту, Салем, Індія

3, Міа, Бангалор, Індія

5, chapie, Лос-Анджелес, США

Внутрішнє з'єднання

ВИБЕРІТЬ * ІЗ table1 INNER JOIN table2 ON (table1.id = table2.id);

1 wqe chennai Індія 1 wqe chennai Індія

2 сту салем Індія 2 сту салем Індія

3 міа Бангалор Індія 3 міа Бангалор Індія

Зліва приєднатися

ВИБЕРІТЬ * ІЗ table1 LEFT JOIN table2 ON (table1.id = table2.id);

1 wqe chennai Індія 1 wqe chennai Індія

2 сту салем Індія 2 сту салем Індія

3 міа Бангалор Індія 3 міа Бангалор Індія

4 yepie newyork США NULL NULL NULL NULL

Зліва приєднатися

ВИБЕРІТЬ * З таблиці1 ЛІВО НАПІВМІСТУ таблиці2 УВІМКНЕНО (table1.id = table2.id);

1 wqe Ченнаї, Індія

2 сту салем Індія

3 міа Бангалор Індія

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


1

Спроба зобразити діаграми Венна для кращого розуміння ..

Ліве напівприєднання: напівз'єднання повертає значення з лівого боку відношення, яке збігається з правим . Його також називають лівим напівз’єднанням.

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

Примітка: Існує ще одна річ, яка називається лівим антиприєднанням: антиприєднання повертає значення з лівого відношення, яке не збігається з правим . Його також називають лівим антиприєднанням.

Внутрішнє приєднання : воно вибирає рядки, що мають відповідні значення в обох відносинах.

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

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