Ключевое слово join в SQL используется при построении select выражений. �?нструкция Join позволяет объединить колонки из нескольких таблиц в одну. Объединение происходит временное и целостность таблиц не нару�?ается. Существует три типа join-выражений:
- inner join;
- outer join;
- cross join;
В свою очередь, outer join может быть left, right и full (слово outer обычно опускается).
В качестве примера (DBMS Oracle) создадим две простые таблицы и сконструируем для них SQL-выражения с использованием join.
В первой таблице будет хранится ID пользователя и его nick-name, а во второй - ID ресурса, имя ресурса и ID пользователя, который может этот ресурс администрировать.
create table t_users (
t_id number(11, 0),
t_nick varchar(16),
primary key (t_id) )
create table t_resources (
t_id number(11, 0),
t_name varchar(16),
t_userid number (11, 0),
primary key (t_id) )
Содержимое таблиц пусть будет таким:
T_ID T_NICK
1 user1
3 user3
4 user4
T_ID T_NAME T_USERID
1 res1 3
2 res2 1
3 res3 2
5 res5 3
Конструкция join выглядит так:
... join_type join table_name on condition …
Где join_type - тип join-выражения, table_name - имя таблицы, которая присоединяется к результату, condition - условие объединения таблиц.
Кострукция join располагается сразу после select-выражения. Можно использовать несколько таких конструкций подряд для объединения соответствующего кол-ва таблиц. Логичнее всего использовать join в том случае, когда таблица имеет вне�?ний ключ (foreign key).
Inner join необходим для получения только тех строк, для которых существует соответствие записей главной таблицы и присоединяемой. �?ными словами условие condition должно выполняться всегда. Пример:
select t_resources.t_name, t_users.t_nick
from t_resources
inner join t_users on t_users.t_id = t_resources.t_userid
Результат будет таким:
T_NAME T_NICK
res2 user1
res1 user3
res5 user3
В случае с left join из главной таблицы будут выбраны все записи, даже если в присоединяемой таблице нет совпадений, то есть условие condition не учитывает присоединяемую (правую) таблицу. Пример:
select t_resources.t_name, t_users.t_nick
from t_resources
left join t_users on t_users.t_id = t_resources.t_userid
Результат выполнения запроса:
T_NAME T_NICK
res1 user3
res2 user1
res3 (null)
res5 user3
Результат показывает все ресурсы и их администраторов, вне зависимотсти от того есть они или нет.
Right join отображает все строки удовлетворяющие правой части условия condition, даже если они не имеют соответствия в главной (левой) таблице:
select t_resources.t_name, t_users.t_nick
from t_resources
right join t_users on t_users.t_id = t_resources.t_userid
А результат будет следующим:
T_NAME T_NICK
res2 user1
res1 user3
res5 user3
(null) user4
Результирующая таблица показывает ресурсы и их администраторов. Если адмнистратор не задействован, эта запись тоже будет отображена. Такое может случиться, например, если ресурс был удален.
Updated (8.03.2007):
Full outer join (ключевое слово outer можно опустить) необходим для отображения всех возможных комбинаций строк из нескольких таблиц. �?ными словами, это объединение результатов left и right join.
select t_resources.t_name, t_users.t_nick
from t_resources
full join t_users on t_users.t_id = t_resources.t_userid
А результат будет таким:
T_NAME T_NICK
res1 user3
res2 user1
res3 (null)
res5 user3
(null) user4
Некоторые СУБД не поддерживают такую функциональность (например, MySQL), в таких случаях обычно используют объединение двух запросов:
select t_resources.t_name, t_users.t_nick
from t_resources
left join t_users on t_users.t_id = t_resources.t_userid
union
select t_resources.t_name, t_users.t_nick
from t_resources
right join t_users on t_users.t_id = t_resources.t_userid
Наконец, cross join. Этот тип join еще называют декартовым произведением (на английском - cartesian product). Настоятельно рекомендую использовать его с умом, так как время выполнения запроса с увеличением числа таблиц и строк в них растет по экспоненте.
Вот пример запроса, который аналогичен cross join:
select t_resources.t_name, t_users.t_nick
from t_resources, t_users
Конструкция Join (в сочетании с другими SQL конструкциями, например, group by) часто встречается при программировании под базы данных. Думаю, эта статья будет вам полезна. Кстати, для проверки своих знаний в области баз данных (и в частности Oracle) рекомендую воспользоваться этим сайтом онлайн тестирования - Тесты по базам данных.
khpi-iip.mipk.kharkiv.edu/library/extent/dbms/s...Внешнее соединение включает в себя внутреннее соединение, а также некоторые строки, отсутствующие в результате внутреннего соединения. Типы внешних соединений:
левое внешнее соединение - внутреннее соединение и строки левой таблицы, которым нет соответствия в правой таблице;
правое внешнее соединение - внутреннее соединение и строки правой таблицы, которым нет соответствия в левой таблице;
полное внешнее соединение - внутреннее соединение и строки правой таблицы, которым нет соответствия в левой таблице, и строки правой таблицы, которым нет соответствия в левой таблице.
3.4.3 Внешние соединения в Oracle
В Oracle внешнее соединение реализуется специальной операцией - операцией (+). Эта операция применяется к столбцу той таблицы, которая дополняет строку пустыми значениями. Ограничения на применение операции следующие:
(+) можно применять только к столбцу, а не к выражению; если столбец участвует в выражении, (+) ставится при столбце;
предикаты, содержащие (+), не могут комбинироваться с помощью операции OR;
в одном подзапросе возможно левое или правое внешнее соединение, но не полное внешнее соединение.
Реализации запросов п.3.4.1 в Oracle будут иметь вид: 1).
SELECT name, m_name
FROM dep, mng
WHERE dep.dep_id=mng.dep_id
2).
SELECT name, m_name
FROM dep, mng
WHERE dep.dep_id=mng.dep_id(+)
3).
SELECT name, m_name
FROM dep, mng
WHERE dep.dep_id(+)=mng.dep_id
4). Простого решения для полного внешнего соединения нет, его можно получить объединением левого и правого внешних соединений:
SELECT name, m_name
FROM dep, mng
WHERE dep.dep_id=mng.dep_id(+)
UNION
SELECT name, m_name
FROM dep, mng
WHERE dep.dep_id(+)=mng.dep_id
"+" ставим не возле той таблицы, записи которой выводим, а возле справочника. Если хотим получить полный список данных, даже если в справочнике записи не будет.