Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
conspect.pdf
Скачиваний:
376
Добавлен:
17.03.2016
Размер:
27.86 Mб
Скачать

Базы данных

БГУИР, ПОИТ

 

 

6.4. Запросы на объединение (JOIN)

6.4.1. Назначение и общая структура JOIN

Запросы на объединение выполнятся в случае, когда данные, необходимые для получения конечной выборки, находятся в разных таблицах (или в одной таблице, представляя собой иерархическую структуру) и при этом между такими данными существует некая логическая или семантическая связь.

Общая структура JOIN такова:

table_references:

table_reference [, table_reference] ...

table_reference: table_factor

| join_table

table_factor:

tbl_name [[AS] alias] [index_hint_list] | table_subquery [AS] alias

| ( table_references )

| { OJ table_reference LEFT OUTER JOIN table_reference ON conditional_expr }

join_table:

table_reference [INNER | CROSS] JOIN table_factor [join_condition] | table_reference STRAIGHT_JOIN table_factor

| table_reference STRAIGHT_JOIN table_factor ON conditional_expr

| table_reference {LEFT|RIGHT} [OUTER] JOIN table_reference join_condition | table_reference NATURAL [{LEFT|RIGHT} [OUTER]] JOIN table_factor

join_condition:

ON conditional_expr | USING (column_list)

index_hint_list:

index_hint [, index_hint] ...

index_hint:

USE {INDEX|KEY}

[FOR {JOIN|ORDER BY|GROUP BY}] ([index_list]) | IGNORE {INDEX|KEY}

[FOR {JOIN|ORDER BY|GROUP BY}] (index_list) | FORCE {INDEX|KEY}

[FOR {JOIN|ORDER BY|GROUP BY}] (index_list)

index_list:

index_name [, index_name] ...

Стр: 182/248

Базы данных

БГУИР, ПОИТ

 

 

Если рассмотреть подробнее каждую секцию JOIN, получится:

Основная часть запроса (также известна как «JOIN-выражение»), применяется совместно с операторами SELECT, DELETE и UPDATE.

Описывает перечень таблиц и способ объединения. (Будет рассмотрено дальше на примерах.)

Описывает условие объединения. (Будет рассмотрено дальше на примерах.)

Описывает «подсказки» по использованию индексов. (См. соответствующий раздел: «Подсказки» по индексам».)

Стр: 183/248

Базы данных

БГУИР, ПОИТ

 

 

6.4.2. Принципы работы JOIN

JOIN позволяет выполнить запрос, объединяющий данные из одной (selfjoin), двух и более таблиц.

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

В общем случае использование JOIN необходимо для денормализации с целью агрегирования или кэширования данных, распределённых по нормализованным отношениям (таблицам) базы данных.

6.4.3. Три простых примера использования JOIN

Для начала рассмотрим три простых примера использования JOIN. Для этого создадим три таблицы (`rooms`, `computers`, `sitepages`) и наполним их небольшим количеством данных.

Таблицы `rooms` и `computers` будут связаны связью «один ко многим».

В таблице `sitepages` будет рекурсивный внешний ключ (ссылка на родительскую страницу).

CREATE TABLE `rooms`

(

`r_id` int(11) NOT NULL AUTO_INCREMENT, `r_name` varchar(255) NOT NULL, PRIMARY KEY (`r_id`)

)

ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `computers`

(

`c_id` int(11) NOT NULL AUTO_INCREMENT, `c_room` int(11) DEFAULT NULL, `c_name` varchar(255) NOT NULL, PRIMARY KEY (`c_id`),

KEY `c_room` (`c_room`), CONSTRAINT `computers_ibfk_1` FOREIGN KEY (`c_room`) REFERENCES `rooms` (`r_id`) ON DELETE CASCADE

ON UPDATE CASCADE

)

ENGINE=InnoDB DEFAULT CHARSET=utf8

CREATE TABLE `sitepages`

(

`p_id` int(11) NOT NULL AUTO_INCREMENT, `p_parent` int(11) DEFAULT NULL, `p_name` varchar(255) NOT NULL, PRIMARY KEY (`p_id`),

KEY `p_parent` (`p_parent`), CONSTRAINT `sitepages_ibfk_1` FOREIGN KEY (`p_parent`)

REFERENCES `sitepages` (`p_id`) ON DELETE CASCADE

ON UPDATE CASCADE

)

ENGINE=InnoDB DEFAULT CHARSET=utf8

Стр: 184/248

Базы данных

БГУИР, ПОИТ

 

 

Схема базы данных приобретает такой вид:

Таблицы с данными:

Таблица

Данные

`rooms`

`computers`

`sitepages`

(Справа показана сохранённая в таблице структура.)

Стр: 185/248

Базы данных

БГУИР, ПОИТ

 

 

Пример 1: показать список комнат и поставленных в них компьютеров.

Запрос

 

SELECT `r_name`, `c_name`

 

 

 

FROM `rooms` JOIN `computers`

 

 

 

ON `r_id`=`c_room`

 

Результат

 

 

 

 

 

 

 

Пример 2: показать список ВСЕХ комнат (даже пустых) и ВСЕХ компьютеров (даже тех, что никуда не поставлены).

Запрос

 

(SELECT `r_name`, `c_name` FROM `rooms` LEFT OUTER JOIN `comput-

 

 

 

ers` ON `r_id`=`c_room`)

 

 

 

UNION DISTINCT

 

 

 

(SELECT `r_name`, `c_name` FROM `rooms` RIGHT OUTER JOIN `comput-

 

 

 

ers` ON `r_id`=`c_room`)

 

Результат

 

 

 

 

 

 

 

Стр: 186/248

Базы данных

БГУИР, ПОИТ

 

 

Пример 3: показать все страницы сайта первых трёх уровней с их родителями.

Запрос

 

SELECT `level1`.`p_parent`, `level1`.`p_name`, `lev-

 

 

 

el2`.`p_parent`, `level2`.`p_name`, `level3`.`p_parent`, `lev-

 

 

 

el3`.`p_name` FROM `sitepages` AS `level1` LEFT OUTER JOIN

 

 

 

`sitepages` AS `level2` ON `level1`.`p_id`=`level2`.`p_parent`

 

 

 

LEFT OUTER JOIN `sitepages` AS `level3` ON `lev-

 

 

 

el2`.`p_id`=`level3`.`p_parent` WHERE ISNULL(`level1`.`p_parent`)

 

Результат

 

 

 

 

 

 

 

Кто-то может подумать, что это – не такие уж и простые примеры. Так вот – нет, вполне простые. Чтобы лучше понять, как и что в них работает – поэкспериментируйте. Вот вам дамп базы.

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

SET time_zone = "+00:00";

/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */;

--

-- Table structure for table `computers`

--

CREATE TABLE IF NOT EXISTS `computers` ( `c_id` int(11) NOT NULL AUTO_INCREMENT, `c_room` int(11) DEFAULT NULL,

`c_name` varchar(255) NOT NULL, PRIMARY KEY (`c_id`),

KEY `c_room` (`c_room`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--

-- Dumping data for table `computers`

--

INSERT INTO `computers` (`c_id`, `c_room`, `c_name`) VALUES (1, 1, 'FirstCompInRoomOne'),

(2, 1, 'SecondCompInRoomOne'), (3, 2, 'SingleCompInRoomTwo'), (4, NULL, 'FreeCompOne'),

(5, NULL, 'FreeCompTwo');

--

-- Table structure for table `rooms`

--

CREATE TABLE IF NOT EXISTS `rooms` ( `r_id` int(11) NOT NULL AUTO_INCREMENT, `r_name` varchar(255) NOT NULL,

PRIMARY KEY (`r_id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;

--

-- Dumping data for table `rooms`

--

INSERT INTO `rooms` (`r_id`, `r_name`) VALUES (1, 'RoomWithTwoComps'),

(2, 'RoomWithOneComp'), (3, 'EmptyRoomOne'), (4, 'EmptyRoomTwo');

Стр: 187/248

Базы данных БГУИР, ПОИТ

--

-- Table structure for table `sitepages`

--

CREATE TABLE IF NOT EXISTS `sitepages` ( `p_id` int(11) NOT NULL AUTO_INCREMENT, `p_parent` int(11) DEFAULT NULL, `p_name` varchar(255) NOT NULL,

PRIMARY KEY (`p_id`),

KEY `p_parent` (`p_parent`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=6 ;

--

-- Dumping data for table `sitepages`

--

INSERT INTO `sitepages` (`p_id`, `p_parent`, `p_name`) VALUES (1, NULL, 'Main'),

(2, 1, 'Contacts'), (3, 1, 'Documents'), (4, 3, 'Templates'), (5, 3, 'Examples');

--

-- Constraints for table `computers`

--

ALTER TABLE `computers`

ADD CONSTRAINT `computers_ibfk_1` FOREIGN KEY (`c_room`) REFERENCES `rooms` (`r_id`) ON DELETE CASCADE ON UPDATE CASCADE;

--

-- Constraints for table `sitepages`

--

ALTER TABLE `sitepages`

ADD CONSTRAINT `sitepages_ibfk_1` FOREIGN KEY (`p_parent`) REFERENCES `sitepages` (`p_id`) ON DELETE CASCADE ON UPDATE CASCADE;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;

Стр: 188/248

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]