4 мая 2011 г.

oracle: join

Ключевое слово 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 users (
    id number(5),
    name varchar(40),
    primary key (id)
    );

create table users_res (
    id number(5),
    res varchar(40),
    users_id number(5),
    primary key (id)
    );

Содержимое таблиц пусть будет таким:
insert into users values(1,'user1');
insert into users values(3,'user3');
insert into users values(4,'user4');
insert into users values(5,'user5');

insert into users_res values(1,'res_1',3);
insert into users_res values(2,'res_2',1);
insert into users_res values(3,'res_3',2);
insert into users_res values(4,'res_4',4);

users
====
ID    NAME
1    user1
3    user3
4    user4
5    user5

users_res
=========
ID    RES    USERS_ID
1    res1    3
2    res2    1
3    res3    2
4    res4    4

inner join
необходим для получения только тех строк, для которых существует соответствие записей главной таблицы и присоединяемой. Иными словами условие condition должно выполняться всегда.
Пример:
select r.res, u.name
from users_res r
join users u on u.id=r.users_id;

Результат будет таким:
RES    NAME
res1    user3
res2    user1
res4    user4

left join
из главной таблицы будут выбраны все записи, даже если в присоединяемой таблице нет совпадений, то есть условие condition не учитывает присоединяемую (правую) таблицу.
Пример:
select r.res, u.name
from users_res r
left join users u on u.id=r.users_id;

Результат выполнения запроса:
RES    NAME
res2    user1
res1    user3
res4    user4
res3    (null)

Результат показывает все ресурсы и их администраторов, вне зависимотсти от того есть они или нет.

right join
отображает все строки удовлетворяющие правой части условия condition, даже если они не имеют соответствия в главной (левой) таблице:
select r.res, u.name
from users_res r
right join users u on u.id=r.users_id;

А результат будет следующим:
RES        NAME
res1        user3
res2        user1
res4        user4
(null)    user5

Результирующая таблица показывает ресурсы и их администраторов. Если адмнистратор не задействован, эта запись тоже будет отображена. Такое может случиться, например, если ресурс был удален.

full outer join 
(ключевое слово outer можно опустить) необходим для отображения всех возможных комбинаций строк из нескольких таблиц. Иными словами, это объединение результатов left и right join.

select r.res, u.name
from users_res r
full join users u on u.id=r.users_id;

А результат будет таким:
RES        NAME
res2        user1
res1        user3
res4        user4
res3        (null)
(null)    user5

cross join 
Этот тип join еще называют декартовым произведением (на английском - cartesian product). Настоятельно рекомендую использовать его с умом, так как время выполнения запроса с увеличением числа таблиц и строк в них растет по экспоненте.
Вот пример запроса, который аналогичен cross join:

select r.res, u.name
from users_res r, users u;