A | B | |||
a | b | c | d | |
1 | 2 | 2 | 4 | |
2 | 1 | 3 | 3 |
Результат запроса
SELECT * FROM A, B; |
a | b | c | d |
1 | 2 | 2 | 4 |
1 | 2 | 3 | 3 |
2 | 1 | 2 | 4 |
2 | 1 | 3 | 3 |
Поэтому перечисление таблиц, как правило, используется совместно с условием соединения записей из разных таблиц, указываемым в предложении WHERE. Для приведенных выше таблиц таким условием может быть совпадение значений, скажем, в полях a и c:
SELECT * FROM A, B WHERE a=c; |
Теперь результатом выполнения этого запроса будет следующая таблица:
a | b | c | d |
2 | 1 | 2 | 4 |
т.е. соединяются только те строки таблиц, у которых в указанных полях находятся равные значения (эквисоединение). Естественно, могут быть использованы любые условия, хотя эквисоединение используется чаще всего, поскольку эта операция воссоздает некую сущность, декомпозированную на две других в результате процедуры нормализации.
Если разные таблицы имеют столбцы с одинаковыми именами, то для однозначности требуется использовать точечную нотацию:
<имя таблицы>.<имя поля>
В тех случаях, когда это не вызывает неоднозначности, использование данной нотации не является обязательным.
Пример. Найти номер модели и производителя ПК, имеющих цену менее $600:
SELECT DISTINCT PC.model, maker FROM PC, Product WHERE PC.model = Product.model AND price < 600; |
model | maker |
1232 | A |
1260 | E |
Иногда в предложении FROM требуется указать одну и ту же таблицу несколько раз. В этом случае обязательным является переименование.
Пример. Вывести пары моделей, имеющих одинаковые цены:
SELECT DISTINCT A.model AS model_1, B.model AS model_2 FROM PC AS A, PC B WHERE A.price = B.price AND A.model < B.model; |
model_1 | model_2 |
1232 | 1233 |
1232 | 1260 |
Переименование также требуется, если в предложении FROM используется подзапрос. Так, первый пример можно переписать следующим образом:
SELECT DISTINCT PC.model, maker FROM PC, (SELECT maker, model FROM Product) AS prod WHERE PC.model = prod.model AND price < 600; |
Обратите внимание, что в этом случае в других предложениях оператора SELECT уже нельзя использовать квалификатор Product, поскольку таблица Product уже не используется. Вместо него используется псевдоним prod. Кроме того, ссылаться теперь можно только на те поля таблицы Product, которые перечислены в подзапросе.
FROM <таблица 1>
[INNER]
| {{LEFT | RIGHT | FULL } [OUTER]} JOIN <таблица 2>
[ON <предикат>]
Соединение может быть либо внутренним (INNER), либо одним из внешних (OUTER). Служебные слова INNER и OUTER можно опускать, поскольку внешнее соединение однозначно определяется его типом - LEFT (левое), RIGHT (правое) или FULL (полное), а просто JOIN будет означать внутреннее соединение.
Предикат определяет условие соединения строк из разных таблиц. При этом INNER JOIN означает, что в результирующий набор попадут только те соединения строк двух таблиц, для которых значение предиката равно TRUE. Как правило, предикат определяет эквисоединение по внешнему и первичному ключам соединяемых таблиц, хотя это не обязательно.
Пример. Найти производителя, номер модели и цену каждого компьютера, имеющегося в базе данных:
SELECT maker, Product.model AS model_1, PC.model AS model_2, price FROM Product INNER JOIN PC ON PC.model = Product.model ORDER BY maker, PC.model; |
maker | model_1 | model_2 | price |
A | 1232 | 1232 | 600.0 |
A | 1232 | 1232 | 400.0 |
A | 1232 | 1232 | 350.0 |
A | 1232 | 1232 | 350.0 |
A | 1233 | 1233 | 600.0 |
A | 1233 | 1233 | 950.0 |
A | 1233 | 1233 | 980.0 |
B | 1121 | 1121 | 850.0 |
B | 1121 | 1121 | 850.0 |
B | 1121 | 1121 | 850.0 |
E | 1260 | 1260 | 350.0 |
Внешнее соединение LEFT JOIN означает, что помимо строк, для которых выполняется условие предиката, в результирующий набор попадут все остальные строки из первой таблицы (левой). При этом отсутствующие значения полей из правой таблицы будут заполнены NULL-значениями.
Пример. Привести все модели ПК, их производителей и цену:
SELECT maker, Product.model AS model_1, PC.model AS model_2, price FROM Product LEFT JOIN PC ON PC.model = Product.model WHERE type = 'PC' ORDER BY maker, PC.model; |
maker | model_1 | model_2 | price |
A | 1232 | 1232 | 600.0 |
A | 1232 | 1232 | 400.0 |
A | 1232 | 1232 | 350.0 |
A | 1232 | 1232 | 350.0 |
A | 1233 | 1233 | 600.0 |
A | 1233 | 1233 | 950.0 |
A | 1233 | 1233 | 980.0 |
B | 1121 | 1121 | 850.0 |
B | 1121 | 1121 | 850.0 |
B | 1121 | 1121 | 850.0 |
E | 2111 | NULL | NULL |
E | 2112 | NULL | NULL |
E | 1260 | 1260 | 350.0 |
Поскольку моделей 2111 и 2112 из таблицы Product нет в таблице PC, в полях
из таблицы PC содержится NULL.
Соединение RIGHT JOIN обратно соединению LEFT JOIN, т.е. в результирующий
набор попадут все строки из второй таблицы, которые будут соединяться только с теми
строками из первой таблицы, для которых выполняется условие соединения.
В нашем случае левое соединение
Product LEFT JOIN PC ON PC.model = Product.model
будет эквивалентно правому соединению
PC RIGHT JOIN Product ON PC.model = Product.model
Запрос же
SELECT maker, Product.model AS model_1, PC.model AS model_2, price FROM Product RIGHT JOIN PC ON PC.model = Product.model ORDER BY maker, PC.model; |
SELECT A.*, B.* FROM A FULL JOIN B ON A.a = B.c; |
a | b | c | d |
1 | 2 | NULL | NULL |
2 | 1 | 2 | 4 |
NULL | NULL | 3 | 3 |
Заметим, что это соединение симметрично, т.е. "A FULL JOIN B" эквивалентно "B FULL JOIN A". Обратите также внимание на обозначение A.*, что означает "все поля таблицы А".
Начало | Упражнения SELECT (рейтинговые этапы) | Упражнения DML | Разработчики |