воскресенье, 29 января 2012 г.

Визуальное представление SQL запросов с JOIN

Использование JOIN в SQL запросах гораздо проще понять если отобразить их в диаграммах Эйлера-Венна. Когда я изучал SQL мне попались только англоязычные материалы. Ligaya Turmelle и Jeff Atwood. Надеюсь этот материал поможет русскоязычным коллегам.

Для экспериментов используется две таблицы.
Таблица А:
create table `tableA` ( `id` int, `name` varchar(30) );
insert into `tableA` ( `id`, `name` ) values ( 1, 'Pirate' ), ( 2, 'Monkey' ), ( 3, 'Ninja' ), ( 4, 'Spaghetti' );
+------+-----------+
| id   | name      |
+------+-----------+
|    1 | Pirate    |
|    2 | Monkey    |
|    3 | Ninja     |
|    4 | Spaghetti |
+------+-----------+

Таблица B:
create table `tableB` ( `id` int, `name` varchar(30) );
insert into `tableB` ( `id`, `name` ) values ( 1, 'Rutabaga' ), ( 2, 'Pirate' ), ( 3, 'Darth Vader' ), ( 4, 'Ninja' );
+------+-------------+
| id   | name        |
+------+-------------+
|    1 | Rutabaga    |
|    2 | Pirate      |
|    3 | Darth Vader |
|    4 | Ninja       |
+------+-------------+


1. INNER JOIN

select * from tableA inner join tableB on tableA.name = tableB.name;
+------+--------+------+--------+
| id   | name   | id   | name   |
+------+--------+------+--------+
|    1 | Pirate |    2 | Pirate |
|    3 | Ninja  |    4 | Ninja  |
+------+--------+------+--------+

Выбираются строки из таблицы A и B, в которых есть одинаковые ключевые значения и в таблице A и в таблице B.

2. FULL OUTER JOIN

select * from tableA full outer join tableB on tableA.name = tableB.name;
+------+-----------+------+-------------+
| 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 |
+------+-----------+------+-------------+

Выбираются все строки из таблицы A и B. Строки с одинаковыми ключевыми значениями объединяются в одну. Записи у которых нет одинаковых ключевых значений в другой таблице, добавляются в результирующую таблицу с полями NULL.

3. LEFT OUTER JOIN

select * from tableA left outer join tableB on tableA.name = tableB.name;
+------+-----------+------+--------+
| id   | name      | id   | name   |
+------+-----------+------+--------+
|    1 | Pirate    |    2 | Pirate |
|    2 | Monkey    | NULL | NULL   |
|    3 | Ninja     |    4 | Ninja  |
|    4 | Spaghetti | NULL | NULL   |
+------+-----------+------+--------+

Выбираются все строки из таблицы A и те строки из таблицы B у которых есть одинаковые ключевые значения. Те строки из таблицы A, для которых не нашлось строк из таблицы B, добавляются в результирующую таблицу с полями  NULL.

4. LEFT OUTER JOIN с исключением

select * from tableA left outer join tableB on tableA.name = tableB.name where TableB.id is null;
+------+-----------+------+------+
| id   | name      | id   | name |
+------+-----------+------+------+
|    2 | Monkey    | NULL | NULL |
|    4 | Spaghetti | NULL | NULL |
+------+-----------+------+------+

Выбираются только те записи из таблицы A, для которых нет одинаковых ключевых значений в таблице B.

5. FULL OUTER JOIN с исключением

select * from tableA full outer join tableB on tableA.name = tableB.name where tableA.id is null or tableB.id is null;
+------+-----------+------+-------------+
| id   | name      | id   | name        |
+------+-----------+------+-------------+
|    2 | Monkey    | NULL | NULL        |
|    4 | Spaghetti | NULL | NULL        |
| null | null      |    1 | Rutabaga    |
| null | null      |    3 | Darth Vader |
+------+-----------+------+-------------+

Выбираются только те значения из таблицы A и B у которых нет одинаковых ключевых значений. Недостающие поля в результирующей таблице заполняются NULL.

6. CROSS JOIN

select * from tableA cross join tableB;
+------+-----------+------+-------------+
| id   | name      | id   | name        |
+------+-----------+------+-------------+
|    1 | Pirate    |    1 | Rutabaga    |
|    2 | Monkey    |    1 | Rutabaga    |
|    3 | Ninja     |    1 | Rutabaga    |
|    4 | Spaghetti |    1 | Rutabaga    |
|    1 | Pirate    |    2 | Pirate      |
|    2 | Monkey    |    2 | Pirate      |
|    3 | Ninja     |    2 | Pirate      |
|    4 | Spaghetti |    2 | Pirate      |
|    1 | Pirate    |    3 | Darth Vader |
|    2 | Monkey    |    3 | Darth Vader |
|    3 | Ninja     |    3 | Darth Vader |
|    4 | Spaghetti |    3 | Darth Vader |
|    1 | Pirate    |    4 | Ninja       |
|    2 | Monkey    |    4 | Ninja       |
|    3 | Ninja     |    4 | Ninja       |
|    4 | Spaghetti |    4 | Ninja       |
+------+-----------+------+-------------+

Этот JOIN невозможно однозначно изобразить на диаграмме. Результирующая таблица будет содержать все возможные сочетания из обоих таблиц.

Комментариев нет:

Отправить комментарий