- •1. Выборка данных из одной реляционной таблицы (агрегирование данных без использования подзапросов, но с использованием фраз group by и having).
- •Imia||''||count(imia)
- •2. Выборка данных из реляционной таблицы, соединенной со своей копией (своими копиями)
- •3. Выборка из одной реляционной таблицы с использованием для отбора данных простого подзапроса по другой таблице (другим таблицам).
- •4. Выборка из одной реляционной таблицы с использованием для отбора данных коррелированного подзапроса по другой таблице (другим таблицам).
- •5. Выборка из одной реляционной таблицы с использованием для отбора данных коррелированного подзапроса по той же таблице.
- •6. Выборка данных из реляционных таблиц с использованием вложенных подзапросов.
- •7. Использование объединения (union) при выборке данных из реляционных таблиц.
- •9. Предложения модификации данных (delete, insert и update).
- •8. Использование квантора exists во вложенных подзапросах при выборке данных из реляционных таблиц.
- •10. Создание реляционных таблиц (с использованием фраз для поддержания целостности данных).
- •11. Базовые триггеры (назначение, структура, процедура создания).
- •Альтернативное описание:
- •12. Представления (назначение, процедуры создания и обновления).
Imia||''||count(imia)
------------------ -----------------
Studentov s imenem Галина 24
Studentov s imenem Борис 22
Еще пример:
select grupa,avg(ocenka),studenty.familiia||' '||studenty.imia||' '||studenty.otchestvo
from vedomost,studenty,uchenik
where ocenka in ('2','3','4','5')
and vedomost.nomer in (select nomer
from uchenik
where grupa in( '351','350','352','353')and nachalo = '01-sep-2002')
and studenty.nomer = vedomost.nomer
and uchenik.nomer = vedomost.nomer
and uchenik.nachalo = '01-sep-2002'
group by grupa,studenty.familiia,studenty.imia,studenty.otchestvo
order by 1,2;
результат:
GRUPA AVG(OCENKA) STUDENTY.FAMILIIA||''||STUDENTY.IMIA||''||STUDENTY.OTCHES
---------- ----------- ---------------------------------------------------------
352 4.57894737 Харисов Константин Ирекович
352 5 Пустовой Даниил Юрьевич
353 3.1875 Звягин Дмитрий Владимирович
Ограничения, накладываемые на предложение HAVING те же, что и ограничения для запросов с группировкой, но есть ряд дополнений:
Предложение HAVING должно содержать как минимум одну агрегатную функцию, если это не так, то лучше применять предложение WHERE.
Так как предложение WHERE применимо к отдельным строкам, а предложение HAVING к группам строк и об этом не стоит забывать!
Что касается NULL в условии поиска HAVING, они точно такие же, как и для предложения WHERE, т.е. "Если условие поиска имеет значение NULL, группа строк исключается и строка в результатах запроса для нее не генерируется".
2. Выборка данных из реляционной таблицы, соединенной со своей копией (своими копиями)
Некоторые запросы используют отношения существующие внутри одной таблицы.
Например, требуется вывести список имен всех служащих и их руководителей. Вся эта информация содержится в одной таблице SALESREPS. Каждому служащему соответствует одна строка в таблице SALESREPS, а столбец MANAGER содержит идентификатор служащего, являющегося руководителем! Просто столбец MANAGER, это внешний ключ для самой таблицы SALESREPS!
SELECT EMPS.NAME, MGRS.NAME
FROM SALESREPS EMPS, SALESREPS MGRS
WHERE EMPS.MANAGER = MGRS.EMPL_NUM
-----------------------------------------------------------------------
NAME NAME
------------------------------ ------------------------------
Вася Пупкин Наташа Королева
Маша Распутина Света Разина
Филип Киркоров Игорь Петров
3. Выборка из одной реляционной таблицы с использованием для отбора данных простого подзапроса по другой таблице (другим таблицам).
Вложенный подзапрос - это подзапрос, заключенный в круглые скобки и вложенный в WHERE (HAVING) фразу предложения SELECT или других предложений, использующих WHERE фразу. Вложенный подзапрос может содержать в своей WHERE (HAVING) фразе другой вложенный подзапрос и т.д. Нетрудно догадаться, что вложенный подзапрос создан для того, чтобы при отборе строк таблицы, сформированной основным запросом, можно было использовать данные из других таблиц (например, при отборе блюд для меню использовать данные о наличии продуктов в кладовой пансионата).
Существуют простые и коррелированные вложенные подзапросы. Они включаются в WHERE (HAVING) фразу с помощью условий IN, EXISTS или одного из условий сравнения ( = | <> | < | <= | > | >= ). Простые вложенные подзапросы обрабатываются системой "снизу вверх". Первым обрабатывается вложенный подзапрос самого нижнего уровня. Множество значений, полученное в результате его выполнения, используется при реализации подзапроса более высокого уровня и т.д.
Запросы с коррелированными вложенными подзапросами обрабатываются системой в обратном порядке. Сначала выбирается первая строка рабочей таблицы, сформированной основным запросом, и из нее выбираются значения тех столбцов, которые используются во вложенном подзапросе (вложенных подзапросах). Если эти значения удовлетворяют условиям вложенного подзапроса, то выбранная строка включается в результат. Затем выбирается вторая строка и т.д., пока в результат не будут включены все строки, удовлетворяющие вложенному подзапросу (последовательности вложенных подзапросов).
Простые вложенные подзапросы используются для представления множества значений, исследование которых должно осуществляться в каком-либо предикате IN, что иллюстрируется в следующем примере: выдать название и статус поставщиков продукта с номером 11, т.е. помидоров.
|
Результат: |
SELECT Название, Статус FROM Поставщики WHERE ПС IN ( SELECT ПС FROM Поставки WHERE ПР = 11 ); |
Название Статус СЫТНЫЙ рынок УРОЖАЙ коопторг ЛЕТО агрофирма КОРЮШКА кооператив |
При обработке полного запроса система выполняет прежде всего вложенный подзапрос. Этот подзапрос выдает множество номеров поставщиков, которые поставляют продукт с кодом ПР = 11.
Подзапрос с несколькими уровнями вложенности можно проиллюстрировать на том же примере. Пусть требуется узнать не поставщиков продукта 11, как это делалось в предыдущих запросах, а поставщиков помидоров, являющихся продуктом с номером 11. Для этого можно дать запрос
SELECT Название, Статус
FROM Поставщики
WHERE ПС IN
( SELECT ПС
FROM Поставки
WHERE ПР IN
( SELECT ПР
FROM Продукты
WHERE Продукт = 'Помидоры' ));
Тот же результат можно получить с помощью соединения
SELECT Название, Статус
FROM Поставщики, Поставки, Продукты
WHERE Поставщики.ПС = Поставки.ПС
AND Поставки.ПР = Продукты.ПР
AND Продукт = 'Помидоры';
При выполнении этого компактного запроса система должна одновременно обрабатывать данные из трех таблиц, тогда как в предыдущем примере эти таблицы обрабатываются поочередно. Естественно, что для их реализации требуются различные ресурсы памяти и времени, однако этого невозможно ощутить при работе с ограниченным объемом данных в иллюстративной базе ПАНСИОН.
Подзапрос с оператором сравнения, отличным от IN:
Выдать номера поставщиков, находящихся в том же городе, что и поставщик с номером 6.
|
Результат: |
SELECT ПС FROM Поставщики WHERE Город = ( SELECT Город FROM Поставщики WHERE ПС = 6 ); |
ПС 1 4 6 |
В подобных запросах можно использовать и другие операторы сравнения (<>, <=, <, >= или >), однако, если вложенный подзапрос возвращает более одного значения и не используется оператор IN, будет возникать ошибка.
