В SQL объединение на самом деле является пересечением? И это тоже связь или «Боковой союз»? - PullRequest
9 голосов
/ 25 апреля 2010

Я всегда думал о соединении в SQL как о некой связи между двумя таблицами.

Например,

select e.name, d.name from employees e, departments d 
  where employees.deptID = departments.deptID

В этом случае он связывает две таблицы, чтобы показать каждому сотруднику имя отдела вместо идентификатора отдела. И вроде как "связь" или "союз" в сторону ".

Но, узнав о внутреннем соединении или внешнем соединении, он показывает, что соединение (внутреннее объединение) на самом деле является пересечением.

Например, когда одна таблица имеет идентификаторы 1, 2, 7, 8, а другая таблица имеет только идентификаторы 7 и 8, мы получаем пересечение:

select * from t1, t2 where t1.ID = t2.ID

чтобы получить две записи "7 и 8". Так что это на самом деле пересечение.

Итак, у нас есть «Пересечение» из 2 таблиц. Сравните это с операцией "Союз" на 2 таблицах. Можно ли считать объединение «пересечением»? Но как насчет аспекта "связывания" или "бокового соединения"?

Ответы [ 5 ]

9 голосов
/ 25 апреля 2010

Вот визуальное объяснение соединений SQL от Джеффа, которое может ответить на некоторые ваши вопросы.

5 голосов
/ 25 апреля 2010

Вы на правильном пути; строки, возвращаемые INNER JOIN - это строки, которые удовлетворяют условиям соединения. Но это похоже на пересечение только потому, что вы используете равенство в своем условии соединения, примененном к столбцам из каждой таблицы.

Также имейте в виду, что INTERSECTION уже является операцией SQL и имеет другое значение - и это не то же самое, что JOIN.

SQL JOIN может создать строку нового типа, в которой есть все столбцы из обеих соединенных таблиц. Например: col4, col5 и col6 не существуют в таблице A, но они существуют в результате объединения с таблицей B:

SELECT a.col1, a.col2, a.col3, b.col4, b.col5, b.col6
FROM A INNER JOIN B ON a.col2=b.col5;

SQL INTERSECTION возвращает строки, общие для двух отдельных таблиц, в которых уже должны быть одинаковые столбцы.

SELECT col1, col2, col3 FROM A
INTERSECT
SELECT col1, col2, col3 FROM B;

Это приводит к тому же результату, что и следующее соединение:

SELECT a.col1, a.col2, a.col3
FROM A INNER JOIN B ON a.col1=b.col1 AND a.col2=b.col2 AND a.col3=b.col3;

Не каждая база данных поддерживает оператор INTERSECTION.

2 голосов
/ 25 апреля 2010

Объединение 'links' или erm ... объединяет строки из двух таблиц. Я думаю, что это то, что вы подразумеваете под «объединением в сторону», хотя лично я считаю, что это ужасный способ выразить это. Но есть разные типы объединений, которые делают несколько разные вещи:

  • Внутреннее соединение действительно является пересечением.
  • Полное внешнее соединение - это объединение.

На этой странице в блоге Джеффа Этвуда описаны другие возможности.

0 голосов
/ 07 июня 2016

INNER JOIN рассматривает два NULL с как два разных значения. Таким образом, если вы объединяетесь на основе столбца, который может содержать пустые значения, и если обе таблицы имеют значения NULL в этом столбце, то INNER JOIN будет игнорировать эти строки.

Поэтому, чтобы правильно извлечь все общие строки между двумя таблицами, следует использовать INTERSECT. INTERSECT рассматривает два NULL s как одно и то же значение.

Пример (SQLite):

Создать две таблицы с пустыми столбцами:

CREATE TABLE Table1 (id INT, firstName TEXT);
CREATE TABLE Table2 (id INT, firstName TEXT);

Вставить NULL значения:

INSERT INTO Table1 VALUES (1, NULL);
INSERT INTO Table2 VALUES (1, NULL);

Извлечение общих строк с использованием INNER JOIN (это не показывает вывод):

SELECT * FROM Table1 INNER JOIN Table2 ON 
    Table1.id=Table2.id AND Table1.firstName=Table2.firstName;

Получить общие строки, используя INTERSECT (Это правильно показывает общую строку):

SELECT * FROM Table1 INTERSECT SELECT * FROM Table2;

Вывод:

Несмотря на то, что много раз и INTERSECT, и INNER JOIN можно использовать для получения одинаковых результатов , они не совпадают и должны выбираться в зависимости от ситуации.

0 голосов
/ 04 июля 2015

Внешнее соединение - не связано с - Union или Union All.

Например, 'null' не будет возникать в результате операции Union или Union All, но это будет результатом внешнего соединения.

...