SQL JOIN та різні типи JOIN


Відповіді:


330

Ілюстрація з W3schools :


INNER JOIN - Тільки записи, які відповідають умові в обох таблицях


ЛІВО ПРИЄДНАЙТЕСЬ - Усі записи з таблиці 1 разом із записами, які відповідають умові таблиці 2


ПРАВО ПРИЄДНАЙТЕСЬ - Усі записи з таблиці 2 разом із записами з таблиці 1, які відповідають умові


FULL OUTER JOIN - Поєднання лівої та правої зовнішніх приєднується до відповідного пункту ON, але зберігаючи обидві таблиці



27
@KNU w3fools має дати кредит тому, де вони взяли ідею для фотографій. Див . Візуалізація SQL приєднується до Джеффа Етвуда (так, того, хто є співавтором ТА ) та пов'язаної статті Лігаї Турмельл, де Джефф отримав ідею та пояснив її.
ypercubeᵀᴹ

2
@avi лівий і правий приєднання схожі, якщо вас не турбує, яка є основною таблицею, на якій базується з'єднання.
Ануп

2
@philipxy: Це дивне визначення (навіть якщо ви прав). Але я б краще піти навпаки і почати з перехресного з'єднання, а потім "побудувати" внутрішнє з'єднання поверх нього. Зрештою, сама концепція перехресного з'єднання приводить до недійсності цих неформальних та неточних візуалізацій діаграми Венна ...
Лукас Едер

1
Ці картини, мабуть, означають, що з'єднання - це те саме, що повне зовнішнє з'єднання, а перетин - це те саме, що і внутрішнє з'єднання, наскільки я не знаю.
mightyWOZ

1
@DevDave, бо всупереч поширеній думці - картина не варта тисячі слів. Дивіться наступну відповідь.
hyankov

248

Що таке SQL JOIN?

SQL JOIN це спосіб отримання даних з двох або більше таблиць баз даних.

Чим відрізняються SQL JOINs?

Всього їх п’ять JOIN. Вони є :

  1. JOIN or INNER JOIN
  2. OUTER JOIN

     2.1 LEFT OUTER JOIN or LEFT JOIN
     2.2 RIGHT OUTER JOIN or RIGHT JOIN
     2.3 FULL OUTER JOIN or FULL JOIN

  3. NATURAL JOIN
  4. CROSS JOIN
  5. SELF JOIN

1. ПРИЄДНАЙТЕСЬ або ВНУТРІШНЯ ПРИЄДНАЙТЕСЬ:

У цьому виді а JOINми отримуємо всі записи, які відповідають умові в обох таблицях, а записи в обох таблицях, які не відповідають, не повідомляються.

Іншими словами, INNER JOINзаснований на єдиному факті, що: ТОЛЬКО повинні бути вказані ТОЛЬКІ відповідні записи в ТАКІ.

Зверніть увагу , що JOINбез будь - яких інших JOINключових слів (наприклад INNER, OUTER, LEFTі т.д.) є INNER JOIN. Іншими словами, JOINце синтаксичний цукор для INNER JOIN(див. Різниця між ПРИЄДНАЙТЕСЬ та ВНУТРІШНЬОЮ ПРИЄДНАЙТЕСЬ ).

2. ЗОВНІШНЕ ПРИЄДНАННЯ:

OUTER JOIN витягує

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

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

2.1 ПРИЄДНАЙТЕСЬ ЛІВО ЗОВНІШНЕ або ПРИЄДНАЙТЕСЬ ЛІВО

Це з'єднання повертає всі рядки з лівої таблиці спільно з відповідними рядками з правої таблиці. Якщо у правій таблиці немає стовпців, вони повертають NULLзначення.

2.2 ПРАВИЛЬНЕ ПРИЄДНУЙСЯ ВНУТРІШНО або ПРАВО ПРИЄДНАЙТЕ

Це JOINповертає всі рядки з правої таблиці спільно з відповідними рядками з лівої таблиці. Якщо в лівій таблиці немає стовпців, вони повертають NULLзначення.

2.3 ПОВНІШНІЙ ПРИЄДНАЙТЕСЬ або ПОВНОГО ПРИЄДНАННЯ

Це JOINпоєднує LEFT OUTER JOINі RIGHT OUTER JOIN. Він повертає рядки з будь-якої таблиці, коли умови виконуються, і повертає NULLзначення, коли немає відповідності.

Іншими словами, OUTER JOINце засновано на тому, що: ТОЛЬКО повинні бути перераховані відповідні записи в ОДНІЙ з таблиць (ВПРАВО або ВЛІВО) або ВІД СТОЛІТЬ таблиць (ПОВНО).

Note that `OUTER JOIN` is a loosened form of `INNER JOIN`.

3. ПРИРОДНИЙ ПРИЄДНАЙТЕСЬ:

Він заснований на двох умовах:

  1. значення JOINробиться на всіх стовпцях з однаковою назвою для рівності.
  2. Видаляє повторювані стовпці з результату.

Це, здається, більше теоретичного характеру, і в результаті (мабуть) більшість СУБД навіть не намагаються це підтримати.

4. КРОВИЙ ПРИЄДНАЙТЕСЬ:

Це декартовий продукт двох задіяних таблиць. Результат CROSS JOINзаповіту не матиме сенсу в більшості ситуацій. Більше того, нам це взагалі не знадобиться (або потрібно найменше, якщо бути точним).

5. САМО ПРИЄДНАЙТЕСЬ:

Це не інша форма JOIN, а скоріше це JOIN( INNER, OUTERі т.д.) таблиці для себе.

ПРИЄДНАЄТЬСЯ на базі Операторів

Залежно від оператора, який використовується для JOINпункту, може бути два типи JOINs. Вони є

  1. Equi ПРИЄднуйтесь
  2. Theta ПРИЄДНАЙТЕСЬ

1. Equi ПРИЄДНАЙТЕСЬ:

Для будь-якого JOINтипу ( INNER, OUTERі т. Д.), Якщо ми використовуємо ТІЛЬКИ оператор рівності (=), то ми говоримо, що JOINє an EQUI JOIN.

2. Theta ПРИЄДНАЙТЕСЬ:

Це те саме, EQUI JOINале це дозволяє всім іншим операторам, таких як>, <,> = і т.д.

Багато хто вважає , що EQUI JOINі Theta JOINаналогічні INNER, і OUTER т.д. JOINs. Але я переконаний, що це помилка і робить ідеї розпливчастими. Тому що INNER JOINі OUTER JOINт. Д. Всі пов'язані з таблицями та їхніми даними, тоді як EQUI JOINі THETA JOINпов'язані лише з операторами, якими ми користуємося в першій.

Знову ж таки, багато хто вважає їх NATURAL JOINякось "своєрідним" EQUI JOIN. Насправді це правда, через першу умову, про яку я згадав NATURAL JOIN. Однак нам не доведеться обмежувати це лише NATURAL JOINодними. INNER JOINs, OUTER JOINs тощо може бути EQUI JOINтеж.


2
Є порівняно нові
ЛЕСТЕРНІ ПРИЄДНАННЯ. ВИБІРТИ

13
Хоча це здається розумним, я не думаю, що відповіді "що таке SQL приєднання" жодним чином не передають корисну інформацію. Відповідь у цілому - це посилання, написане для людей, які вже розуміють приєднання, а не для людей, які задають ці питання. Він також опускає посилання, як на підтримку своїх тверджень (як це доречно, якщо дають авторську відповідь), так і надати додаткові пояснення через зовнішні ресурси. Якщо ви намагаєтесь написати авторитетну відповідь на прив’язку нових користувачів SQL, можливо, варто трохи заповнити пробіли, особливо частину "що таке приєднання".
Крейг Рінгер

чи можете ви навести кілька прикладів?
аві

67

Визначення:


ПРИЄДНАЄТЬСЯ - це спосіб запиту даних, які поєднуються разом з декількох таблиць одночасно.

Типи приєднання:


Що стосується RDBMS, існує 5 типів приєднань:

  • Equi-Join: Поєднує загальні записи з двох таблиць на основі умови рівності. Технічно об'єднання, виконане за допомогою оператора рівності (=) для порівняння значень первинного ключа однієї таблиці та значень зовнішнього ключа іншої таблиці, отже, набір результатів включає загальні (зіставлені) записи з обох таблиць. Про впровадження див. INNER-JOIN.

  • Natural-Join: Це вдосконалена версія Equi-Join, в якій операція SELECT опускає повторюваний стовпець. Про впровадження див. INNER-JOIN

  • Non-Equi-Join: Це зворотне значення Equi-join, коли умовою приєднання є використання, яке не є рівним оператором (=), наприклад,! =, <=,> =,>, <Або МЕЖДОМ тощо. Про реалізацію див. INNER-JOIN.

  • Self-Join:: індивідуальна поведінка приєднання, де таблиця поєднується з самим собою; Зазвичай це потрібно для запитів таблиць, що самостійно посилаються (або сутності Unar відносин). Про впровадження див. INNER-JOIN.

  • Декартовий продукт: він поєднує всі записи обох таблиць без будь-яких умов. Технічно він повертає набір результатів запиту без WHERE-пункту.

Відповідно до проблеми та прогресу SQL, існують 3 типи з'єднань, і всі з'єднання RDBMS можна досягти, використовуючи ці типи з'єднань.

  1. ВНУТРІШНЯ ПРИЄДНАННЯ: Він об'єднує (або поєднує) збігані рядки з двох таблиць. Узгодження проводиться на основі загальних стовпців таблиць та їх порівняльної роботи. Якщо умова заснована на рівності, тоді: EQUI-JOIN виконується, інакше Non-EQUI-Join.

  2. OUTER-JOIN: Він об'єднує (або поєднує) збігані рядки з двох таблиць і незрівняних рядків із значеннями NULL. Однак можна налаштувати підбір невідповідних рядків, наприклад, вибір не збігається рядка з першої таблиці або другої таблиці за підтипами: ВЛІТТЯ ВІДПРИЄМСТВО ПРИЄДНАЙТЕСЬ та ПРАВИЙ ЗАРІБ.

    2.1. ЛІВНІ ВНУТРІШНІ ПРИЄДНАННЯ (він же, НАЛІГЛО-ПРИЄДНАЙТЕСЬ): Повертає відповідні рядки з двох таблиць і не збігаються з таблицею ВЛЕВО (тобто, перша таблиця).

    2.2. ВПРАВИ ВЗУХОДЖЕННЯ ПРИЄДНАЙТЕСЬ (він же, ПРАВО-ПРИЄДНАЙТЕСЬ): Повертає відповідні рядки з двох таблиць і не збігаються лише з таблиці ПРАВО.

    2.3. ПОВНІШНІЙ ПРИЄДНАЙТЕСЬ (інакше ЗОВНІШНІ ПРИЄДНАННЯ): Повертає зіставлені та не збігаються з обох таблиць.

  3. CROSS-JOIN: Це з'єднання не зливається / комбінується, натомість виконує декартовий продукт.

введіть тут опис зображення Примітка. Самостійне приєднання може бути досягнуто як INNER-JOIN, OUTER-JOIN та CROSS-JOIN на основі вимог, але таблиця повинна приєднуватися сама.

Для отримання додаткової інформації:

Приклади:

1.1: ВНУТРІШНЯ ПРИЄДНАННЯ: Реалізація Equi-Join

SELECT  *
FROM Table1 A 
 INNER JOIN Table2 B ON A.<Primary-Key> =B.<Foreign-Key>;

1.2: ВНУТРІШНЯ ПРИЄДНАННЯ: Реалізація Natural-JOIN

Select A.*, B.Col1, B.Col2          --But no B.ForeignKeyColumn in Select
 FROM Table1 A
 INNER JOIN Table2 B On A.Pk = B.Fk;

1.3: INNER-JOIN з реалізацією NON-Equi

Select *
 FROM Table1 A INNER JOIN Table2 B On A.Pk <= B.Fk;

1.4: ВНУТРІШНЯ ПРИЄДНАЙТЕСЬ із САМОСТІЙНОЮ ПРИЄДНАЙТЕ

Select *
 FROM Table1 A1 INNER JOIN Table1 A2 On A1.Pk = A2.Fk;

2.1: ЗОВНІШНЕ ПРИЄДНАННЯ (повне зовнішнє з'єднання)

Select *
 FROM Table1 A FULL OUTER JOIN Table2 B On A.Pk = B.Fk;

2.2: ПРИЄДНАЙТЕСЬ ЛІВО

Select *
 FROM Table1 A LEFT OUTER JOIN Table2 B On A.Pk = B.Fk;

2.3: ПРАВО ПРИЄДНАЙТЕСЬ

Select *
 FROM Table1 A RIGHT OUTER JOIN Table2 B On A.Pk = B.Fk;

3.1: КРОВИЙ ПРИЄДНАЙТЕСЬ

Select *
 FROM TableA CROSS JOIN TableB;

3.2: CROSS JOIN-Self JOIN

Select *
 FROM Table1 A1 CROSS JOIN Table1 A2;

// АБО //

Select *
 FROM Table1 A1,Table1 A2;

Мітки "Таблиця 1" та "Таблиця 2" та мітки під ними невідповідні, вони є на ілюстраціях intersect// except/ union; тут кола - це рядки, повернені left& right join, як говорять пронумеровані мітки. Зображення AXB - це нісенітниця. cross join= inner join on 1=1& - особливий випадок першої діаграми.
Філіпсі

Варто згадати, що SQL-92 визначає UNION JOIN. Зараз застаріла в SQL: 2003.
The Impaler

40

Цікаво, що більшість інших відповідей страждають від цих двох проблем:

Нещодавно я написав статтю на тему: Напевно, неповний, всебічний посібник з багатьох різних способів приєднатися до таблиць у SQL , який я підсумую тут.

Перше і головне: ПРИЄДНАЙТЕСЬ - це декартові продукти

Ось чому діаграми Венна пояснюють їх настільки неточно, оскільки ПРИЄДНАННЯ створює декартовий продукт між двома об'єднаними таблицями. Вікіпедія це прекрасно ілюструє:

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

Синтаксис SQL для декартових продуктів є CROSS JOIN. Наприклад:

SELECT *

-- This just generates all the days in January 2017
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Here, we're combining all days with all departments
CROSS JOIN departments

Який поєднує всі рядки з однієї таблиці та всі рядки з другої таблиці:

Джерело:

+--------+   +------------+
| day    |   | department |
+--------+   +------------+
| Jan 01 |   | Dept 1     |
| Jan 02 |   | Dept 2     |
| ...    |   | Dept 3     |
| Jan 30 |   +------------+
| Jan 31 |
+--------+

Результат:

+--------+------------+
| day    | department |
+--------+------------+
| Jan 01 | Dept 1     |
| Jan 01 | Dept 2     |
| Jan 01 | Dept 3     |
| Jan 02 | Dept 1     |
| Jan 02 | Dept 2     |
| Jan 02 | Dept 3     |
| ...    | ...        |
| Jan 31 | Dept 1     |
| Jan 31 | Dept 2     |
| Jan 31 | Dept 3     |
+--------+------------+

Якщо ми просто запишемо список розділених комами таблиць, отримаємо те саме:

-- CROSS JOINing two tables:
SELECT * FROM table1, table2

ВНУТРІШНЕ ПРИЄДНАННЯ (Theta-ПРИЄДНАЙТЕСЬ)

А INNER JOIN- просто відфільтрований, CROSS JOINде Thetaв реляційній алгебрі називається предикат фільтра .

Наприклад:

SELECT *

-- Same as before
FROM generate_series(
  '2017-01-01'::TIMESTAMP,
  '2017-01-01'::TIMESTAMP + INTERVAL '1 month -1 day',
  INTERVAL '1 day'
) AS days(day)

-- Now, exclude all days/departments combinations for
-- days before the department was created
JOIN departments AS d ON day >= d.created_at

Зауважте, що ключове слово INNERнеобов’язкове (за винятком MS Access).

( дивіться приклади результатів у статті )

Приєднуйтесь до EQUI

Особливим видом Theta-JOIN є джойні, які ми використовуємо найбільше. Присудок з'єднує первинний ключ однієї таблиці із зовнішнім ключем іншої таблиці. Якщо ми використовуємо базу даних Sakila для ілюстрації, ми можемо написати:

SELECT *
FROM actor AS a
JOIN film_actor AS fa ON a.actor_id = fa.actor_id
JOIN film AS f ON f.film_id = fa.film_id

Це поєднує всіх акторів зі своїми фільмами.

Або також на деяких базах даних:

SELECT *
FROM actor
JOIN film_actor USING (actor_id)
JOIN film USING (film_id)

USING()Синтаксис дозволяє вказати стовпець , який повинен бути присутнім на кожній стороні JOIN таблиці операції і створює предикат рівності цих двох стовпців.

ПРИРОДНА ПРИЄДНАЙТЕСЬ

Інші відповіді вказали цей тип "ПРИЄДНАЙТЕСЬ" окремо, але це не має сенсу. Це просто синтаксична форма цукру для equi ПРИЄДНАЙТЕСЬ, що є особливим випадком Theta-JOIN або INNER JOIN. NATURAL JOIN просто збирає всі стовпці, які є загальними для обох таблиць, що об'єднуються, і приєднує USING()ці стовпці. Що навряд чи корисне через випадкові збіги (як LAST_UPDATEколонки в базі даних Sakila ).

Ось синтаксис:

SELECT *
FROM actor
NATURAL JOIN film_actor
NATURAL JOIN film

ЗОВНІШНЕ ПРИЄДНАЙТЕСЬ

Тепер OUTER JOINтрохи відрізняється від INNER JOINстворення UNIONдекількох декартових продуктів. Ми можемо написати:

-- Convenient syntax:
SELECT *
FROM a LEFT JOIN b ON <predicate>

-- Cumbersome, equivalent syntax:
SELECT a.*, b.*
FROM a JOIN b ON <predicate>
UNION ALL
SELECT a.*, NULL, NULL, ..., NULL
FROM a
WHERE NOT EXISTS (
  SELECT * FROM b WHERE <predicate>
)

Ніхто не хоче писати останнього, тому ми пишемо OUTER JOIN(що зазвичай краще оптимізується базами даних).

Можливо INNER, тут ключове слово OUTERнеобов’язкове.

OUTER JOIN випускається у трьох ароматах:

  • LEFT [ OUTER ] JOIN: Ліва таблиця JOINвиразу додається до об'єднання, як показано вище.
  • RIGHT [ OUTER ] JOIN: Права таблиця JOINвиразу додається до об'єднання, як показано вище.
  • FULL [ OUTER ] JOIN: Обидві таблиці JOINвиразу додаються до об'єднання, як показано вище.

Все це можна поєднувати з ключовим словом USING()або з NATURAL( нещодавно у мене був справжній випадок використанняNATURAL FULL JOIN )

Альтернативні синтаксиси

У Oracle та SQL Server є деякі історичні, застарілі синтаксиси, які підтримували OUTER JOINвже до того, як стандарт SQL мав для цього синтаксис:

-- Oracle
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id = fa.actor_id(+)
AND fa.film_id = f.film_id(+)

-- SQL Server
SELECT *
FROM actor a, film_actor fa, film f
WHERE a.actor_id *= fa.actor_id
AND fa.film_id *= f.film_id

Сказавши це, не використовуйте цей синтаксис. Я просто перелічу це тут, щоб ви могли розпізнати це зі старих публікацій блогу / застарілого коду.

Розділені OUTER JOIN

Мало хто це знає, але стандарт SQL визначає розділений OUTER JOIN(і Oracle реалізує це). Ви можете написати такі речі:

WITH

  -- Using CONNECT BY to generate all dates in January
  days(day) AS (
    SELECT DATE '2017-01-01' + LEVEL - 1
    FROM dual
    CONNECT BY LEVEL <= 31
  ),

  -- Our departments
  departments(department, created_at) AS (
    SELECT 'Dept 1', DATE '2017-01-10' FROM dual UNION ALL
    SELECT 'Dept 2', DATE '2017-01-11' FROM dual UNION ALL
    SELECT 'Dept 3', DATE '2017-01-12' FROM dual UNION ALL
    SELECT 'Dept 4', DATE '2017-04-01' FROM dual UNION ALL
    SELECT 'Dept 5', DATE '2017-04-02' FROM dual
  )
SELECT *
FROM days 
LEFT JOIN departments 
  PARTITION BY (department) -- This is where the magic happens
  ON day >= created_at

Частини результату:

+--------+------------+------------+
| day    | department | created_at |
+--------+------------+------------+
| Jan 01 | Dept 1     |            | -- Didn't match, but still get row
| Jan 02 | Dept 1     |            | -- Didn't match, but still get row
| ...    | Dept 1     |            | -- Didn't match, but still get row
| Jan 09 | Dept 1     |            | -- Didn't match, but still get row
| Jan 10 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 11 | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 12 | Dept 1     | Jan 10     | -- Matches, so get join result
| ...    | Dept 1     | Jan 10     | -- Matches, so get join result
| Jan 31 | Dept 1     | Jan 10     | -- Matches, so get join result

Сенс у тому, що всі рядки з розділеної сторони з'єднання закінчуються результатом, незалежно від того, чи JOINвідповідає щось на "іншій стороні СПОЛУЧЕННЯ". Довга коротка історія. Це для заповнення рідких даних у звітах. Дуже корисний!

SEMI ПРИЄДНАЙТЕСЬ

Серйозно? Жодної іншої відповіді це не отримало? Звичайно, ні, тому що він не має нативного синтаксису в SQL, на жаль (як ANTI JOIN нижче). Але ми можемо використати IN()і EXISTS(), наприклад, знайти всіх акторів, які зіграли у фільмах:

SELECT *
FROM actor a
WHERE EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

WHERE a.actor_id = fa.actor_idПредикат діє як стать предикатів. Якщо ви не вірите, перегляньте плани виконання, наприклад, в Oracle. Ви побачите, що база даних виконує операцію SEMI JOIN, а не EXISTS()предикат.

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

АНТИ ПРИЄДНАЙТЕСЬ

Це як раз зворотне SEMI JOIN ( будьте обережні , щоб не використовувати , NOT INхоча , як це має важливе застереження)

Ось усі актори без фільмів:

SELECT *
FROM actor a
WHERE NOT EXISTS (
  SELECT * FROM film_actor fa
  WHERE a.actor_id = fa.actor_id
)

Деякі люди (особливо люди MySQL) також пишуть АНТИ ПРИЄДНАЙТЕ так:

SELECT *
FROM actor a
LEFT JOIN film_actor fa
USING (actor_id)
WHERE film_id IS NULL

Я думаю, що історичною причиною є продуктивність.

ЛІТЕРАЛЬНЕ ПРИЄДНАННЯ

OMG, це занадто круто. Я єдиний, хто це згадує? Ось класний запит:

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
LEFT OUTER JOIN LATERAL (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  JOIN inventory AS i USING (film_id)
  JOIN rental AS r USING (inventory_id)
  JOIN payment AS p USING (rental_id)
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f
ON true

Він знайде ТОП-5 прибутків фільмів на одного актора. Щоразу, коли вам знадобиться запит TOP-N-на-щось, LATERAL JOINви будете своїм другом. Якщо ви людина SQL Server, то ви знаєте цей JOINтип під назвоюAPPLY

SELECT a.first_name, a.last_name, f.*
FROM actor AS a
OUTER APPLY (
  SELECT f.title, SUM(amount) AS revenue
  FROM film AS f
  JOIN film_actor AS fa ON f.film_id = fa.film_id
  JOIN inventory AS i ON f.film_id = i.film_id
  JOIN rental AS r ON i.inventory_id = r.inventory_id
  JOIN payment AS p ON r.rental_id = p.rental_id
  WHERE fa.actor_id = a.actor_id -- JOIN predicate with the outer query!
  GROUP BY f.film_id
  ORDER BY revenue DESC
  LIMIT 5
) AS f

Добре, можливо, це обман, тому що a LATERAL JOINабо APPLYвираз - це "корельований підпит", який створює кілька рядків. Але якщо ми допускаємо "співвіднесені підзапити", ми також можемо говорити про ...

MULTISET

Це реально реалізовано лише Oracle та Informix (наскільки мені відомо), але це може бути емуляція в PostgreSQL за допомогою масивів та / або XML та в SQL Server за допомогою XML.

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

SELECT a.*, MULTISET (
  SELECT f.*
  FROM film AS f
  JOIN film_actor AS fa USING (film_id)
  WHERE a.actor_id = fa.actor_id
) AS films
FROM actor

Як ви вже бачили, є кілька типів JOIN , ніж просто «нудно» INNER, OUTERі CROSS JOINщо, як правило , згадуються. Детальніше в моїй статті . І будь ласка, перестаньте використовувати схеми Венна для їх ілюстрації.


Еквиджойн - особливий випадок тета-приєднання, де тета - рівність. Theta-join є аналогом окремого випадку внутрішнього з'єднання, де on - тета порівняння стовпця з кожного. Деякі десятиліття після того, як Кодд визначив їх, деякі підручники (і) неправильно визначили тета-об'єднання як узагальнення, яке є аналогом внутрішнього з'єднання.
філіпсі

@philipxy: Що-небудь конкретне, що я повинен змінити у своїй відповіді? Ви можете запропонувати змінити ...
Лукас Едер

10

Я створив ілюстрацію, яка пояснює краще, ніж слова, на мою думку: SQL Приєднати таблицю пояснень


@Niraj Кола A&B не містять рядків A&B. Вони наосліп копіюються з інших місць без кредиту. Перехресне з'єднання входить до внутрішнього випадку з'єднання, це внутрішнє з'єднання на 1 = 1. Яким чином ці частини малюнка «ідеальні»?
Філіпсі

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

-3

Я збираюся підштовхнути свого домашнього улюбленця: ключове слово USING.

Якщо обидві таблиці з обох сторін JOIN мають свої іноземні ключі, правильно названі (тобто, те саме ім'я, а не лише "id"), це можна використовувати:

SELECT ...
FROM customers JOIN orders USING (customer_id)

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


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