class DarkRaha extends com { // разработка приложений
            String a="Главная" b="Контакты" c="О сайте"
};

основы sql

введение
структура БД
инструментарий
комментарий
идентификаторы
обзор типов данных
интервалы времени
литералы
операции и выражения
обзор функций
преобразование типов
создание таблицы
изменение, удаление таблицы
вставка данных
изменение записей
удаление записей
выбор данных
соединения
агрегатные функции, группировка данных
операции над выборками
добавление итогов
нумерация записей
уникальность первич. ключа
индексы
представления

Dynamic SQL

прочее

Справочник по SQL

Соединения

Пусть имеются следующие две таблицы с данными.


-- таблица цветов
create table colors(
id integer,
cname varchar(45), -- название цвета

constraint pk_colors primary key (id)
);

insert into colors values(1,'красный');
insert into colors values(2,'синий');
insert into colors values(3,'зеленый');
insert into colors values(4,'белый');
insert into colors values(5,'черный');
insert into colors values(6,'бурмалиновый');

-- таблица объектов мира
create table objs (
id integer,
oname varchar(45), -- название объекта
fk integer, -- ссылка на цвет объекта

constraint pk_objs primary key (id),
constraint fk_objs foreign key (fk) 
   references colors(id) 
);

insert into objs values(1,'небо',2);
insert into objs values(2,'уголь',5);
insert into objs values(3,'лист',3);
insert into objs values(4,'водка',null );
insert into objs values(5,'ягода',1);

commit;

Ниже приведен пример запроса из двух таблиц без условия соединения. В результате возвращается выборка из 30 записей, где для каждой записи первой таблицы сопоставлены по очереди все записи второй таблицы, или другими словами, все комбинации.
select o.oname, c.cname from objs o, colors c;

Для присоединения к каждой записи первой таблицы, только ту запись из второй таблицы, на которую происходит ссылка, необходимо указать условие. Это можно сделать в конструкции where или в конструкции from. Ниже приведен пример запроса с внутренним соединением.


-- условие в where
select o.oname, c.cname 
  from objs o, colors c 
  where o.fk=c.id;

-- условие в from с помощью
-- конструкции JOIN ON   
select o.oname, c.cname from 
   objs o INNER JOIN colors c ON (o.fk=c.id );

К одному источнику данных можно последовательно присоединять сколько угодно других источников.


select o.oname, c.cname, o2.oname as oname2 
   from 
   (objs o INNER JOIN colors c ON (o.fk=c.id ))
   INNER JOIN (select * from objs ) o2 ON
   (o.id=o2.id) 

В нашем случае внутреннего соединения не достаточно, так как из выборки выпадает запись с пустым значением внешнего ключа. Если же поставить условие "o.fk=c.id or o.fk is null", то вновь получим лишние записи. Данная задача решается с помощью внешних соединений. Если по условию для записи одной таблицы не найдено ни одной записи из другой таблицы, то присоединится пустая запись. Слова одной и другой использованы здесь не случайно. При внешних соединениях явно указывается к какой таблице происходит присоединение. В ниже приведенном примере ключевое слово OUTER в большинстве СУБД можно опустить.


-- присоединяем к левой таблице
-- в результате в выборке будет 5 записей
-- в столбце cname будет одно пустое поле
select o.oname, c.cname from 
   (objs o LEFT OUTER JOIN colors c ON (o.fk=c.id ))

-- присоединяем к правой таблице
-- в результате в выборке будет 6 записей
-- в столбце oname будет два пустых поля
select o.oname, c.cname from 
   (objs o RIGHT OUTER JOIN colors c 
    ON (o.fk=c.id ))

-- в расширении Oracle можно указать (+)
-- в условии для той таблицы, для которой
-- будут генерироваться пустые записи
select o.oname, c.cname 
   from objs o, colors c
   -- присоединяем к левой таблице   
   where o.fk=c.id(+) 
   
select o.oname, c.cname 
   from objs o, colors c
   -- присоединяем к правой таблице
   where o.fk(+)=c.id  

Пустое значение в выборке можно заменить функцией coalesce.


-- в MySQL между coalesce и скобкой не должно 
-- быть пробелов. 
select o.oname, coalesce(c.cname,'цвет не задан')
   from (objs o LEFT OUTER JOIN colors c 
         ON (o.fk=c.id ));

Рейтинг@Mail.ru