2.7. Соединение таблиц
Итак, предположим, что у нас есть два стола. Стол A (TableA) слева, а стол B (TableB) справа. Мы заселим каждый четырьмя персонажами, имена которых могут присутствовать на обоих столах.
TableA |
|
|
TableB |
|
||
|
|
|
|
|
|
|
id |
name |
|
id |
|
name |
|
|
|
|
|
|
|
|
1 |
Pirate |
|
1 |
|
Rutabaga |
|
|
|
|
|
|
|
|
2 |
Monkey |
|
2 |
|
Pirate |
|
|
|
|
|
|
|
|
3 |
Ninja |
|
3 |
|
Darth Vader |
|
|
|
|
|
|
|
|
4 |
Spaghetti |
|
4 |
|
Ninja |
|
|
|
|
|
|
|
|
2.7.1. INNER |
JOIN |
|
|
|
|
|
— INNER |
JOIN производит |
выборку |
записей, которые только |
|||
существуют в TableA и TableB одновременно.
—CROSS JOIN — это эквивалент INNER JOIN.
—INNER JOIN можно заменить условием объединения в WHERE. Запрос:
SELECT * FROM `TableA`
INNER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Идентичный запрос:
SELECT * FROM `TableA`,`TableB`
WHERE `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
3 |
|
Ninja |
4 |
|
Ninja |
|
|
|
|
|
|
2.7.2. FULL OUTER JOIN
*Не доступно в MySQL.
FULL OUTER JOIN производит выборку всех записей из TableA и TableB, вне зависимости есть ли соответствующая запись в соседней таблице. Если таковой нет, то недостающая сторона будет содержать пустой указатель и результатом будет выводится NULL.
Запрос:
SELECT * FROM `TableA`
FULL OUTER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
3 |
|
Ninja |
4 |
|
Ninja |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|
NULL |
|
NULL |
1 |
|
Rutabaga |
|
|
|
|
|
|
NULL |
|
NULL |
3 |
|
Darth Vader |
|
|
|
|
|
|
В MySQL нечто похожее можно получить запросом:
SELECT `TableA`.*, `TableB`.* FROM `TableA`
LEFT JOIN `TableB` USING (`name`)
UNION SELECT `TableA`.*, `TableB`.* FROM `TableB`
LEFT JOIN `TableA`
USING (`name`)
WHERE `TableA`.`name` IS NULL
Результат тот же, что и выше.
Чтобы произвести выборку уникальных записей из двух таблиц (значения одной таблицы отсутствуют в другой), мы воспользуемся тем же FULL OUTER JOIN, указав, что NULL может быть как в результате одной таблицы, так и в результате другой.
Запрос:
SELECT * FROM `TableA`
FULL OUTER JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
WHERE `TableA`.`id` IS NULL OR `TableB`.`id` IS NULL
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|
NULL |
|
NULL |
1 |
|
Rutabaga |
|
|
|
|
|
|
NULL |
|
NULL |
3 |
|
Darth Vader |
|
|
|
|
|
|
В MySQL нечто похожее можно получить запросом:
SELECT `TableA`.*, `TableB`.* FROM
TableA LEFT JOIN `TableB`
USING (`name`)
WHERE `TableB`.`name` IS NULL
UNION SELECT `TableA`.*, `TableB`.* FROM `TableB ` LEFT JOIN `TableA` USING (`name`)
WHERE `TableA`.`name` IS NULL
Результат тот же, что и выше.
2.7.3. LEFT JOIN
LEFT OUTER JOIN (LEFT JOIN) указывает, что левая таблица управляющая (в нашем случае TableA) и производит из нее полную выборку, осуществляя поиск соответствующих записей в таблице TableB. Если таких соответствий не найдено, то база вернет пустой указатель — NULL. Указание OUTER — не обязательно.
Запрос:
SELECT * FROM `TableA`
LEFT JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
Результат:
TableA |
|
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
1 |
|
Pirate |
2 |
|
Pirate |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
3 |
Ninja |
4 |
Ninja |
|
|
|
|
4 |
Spaghetti |
NULL |
NULL |
|
|
|
|
Чтобы произвести выборку записей из таблицы TableA, которых не существует в таблице TableB, мы выполняем LEFT JOIN, но затем из результата исключаем записи, которые не хотим видеть, путем указания, что TableB.id является нулем (указывая, что записи нет в таблице
TableB).
Запрос:
SELECT * FROM `TableA`
LEFT JOIN `TableB`
ON `TableA`.`name` = `TableB`.`name`
WHERE `TableB`.`id` IS NULL
Результат:
|
TableA |
|
TableB |
||
|
|
|
|
|
|
id |
|
name |
id |
|
name |
|
|
|
|
|
|
2 |
|
Monkey |
NULL |
|
NULL |
|
|
|
|
|
|
4 |
|
Spaghetti |
NULL |
|
NULL |
|
|
|
|
|
|