фразе SELECT также можно использовать выражение группировки, однако нельзя выводить по отдельности столбцы, участвующие в этом выражении.
Запрос. Для каждого значения зарплаты, не превышающего 800, вывести это значение и количество преподавателей, такую зарплату получающих.
SELECT Salary + Rise, COUNT(*)
FROM TEACHER
WHERE Salary + Rise <= 800
GROUP BY Salary + Rise;
1.6.3 Условие отбора групп
Предположим, что нужно узнать номера корпусов, суммарное количество мест в аудиториях которых превышает 100. Приведенная ниже формулировка запроса является неверной:
SELECT Building
FROM ROOM
WHERE SUM(Seats) > 100
GROUP BY Building;
-------
Ошибка в строке 3:
ORA-00934: групповая функция здесь не разрешена
Дело в том, что фраза WHERE проверяет на соответствие условию строки исходных таблиц, а мы указали в ней агрегатную функцию. Для отбора строк среди полученных групп следует применять фразу HAVING. Она играет такую же роль для групп, что и фраза WHERE для исходных таблиц, и может исполь-
зоваться лишь при наличии фразы GROUP BY. В предложении SELECT фразы
WHERE, GROUP BY и HAVING обрабатываются в следующем порядке.
1.Фразой WHERE отбираются строки, удовлетворяющие указанному в ней условию.
2.Фраза GROUP BY группирует отобранные строки.
3.Фразой HAVING отбираются группы, удовлетворяющие указанному в ней условию.
В связи с вышесказанным, предыдущий запрос необходимо записать так.
Запрос. Указать корпуса, суммарное количество мест в аудиториях кото-
рых превышает 100.
51
SELECT Building
FROM ROOM
GROUP BY Building
HAVING SUM(Seats) > 100;
1.6.4 Сортировка строк
1.6.4.1 Сортировка по столбцу или выражению Как мы уже отмечали, строки в таблицах базы данных неупорядочены.
Также неупорядочены и строки результирующей таблицы запроса, однако для их упорядочения в предложении SELECT можно воспользоваться фразой
ODER BY. Она сортирует по значению указанных в ней столбцов (и выражений над столбцами) строки результирующей таблицы запроса. Синтаксис этой фра-
зы следующий:
ORDER BY спецификация_сортировки[, спецификация_сортировки]...
где спецификация_сортировки имеет такой синтаксис:
выражение_сортировки [ASC | DESC]
Сортировать можно по столбцам (выражениям) тех типов, для которых определены операции сравнения. Это относится, в частности, к символьным строкам, числам и временным значениям. Можно указывать направление сор-
тировки.
Далее в этом уроке мы рассмотрим общие способы упорядочения резуль-
тирующих строк. Правила и возможности сортировки при использовании тео-
ретико-множественных операторов изучаются в следующих разделах курса.
Сортировать строки результирующей таблицы запроса можно по отдель-
ным столбцам, совокупности столбцов, а также по одному или нескольким вы-
ражениям над столбцами. Ниже рассматриваются все эти варианты.
Запрос. Вывести алфавитный список фамилий профессоров.
SELECT Name
FROM TEACHER
WHERE LOWER(Post) = 'профессор'
ORDER BY Name;
Запрос. Вывести номера групп и их рейтинг по убыванию рейтинга.
SELECT Num, Rating
FROM SGROUP
52
ORDER BY Rating DESC;
Запрос. Вывести фамилии ассистентов и их зарплату по ее возрастанию.
SELECT Name, Salary + Rise
FROM TEACHER
WHERE LOWER(Post) = 'ассистент'
ORDER BY Salary + Rise;
SQL позволяет упорядочивать строки результирующей таблицы не только по тем столбцам, которые в ней присутствуют, но и по столбцам исходной таб-
лицы и выражениям над ними.
Запрос. Вывести фамилии ассистентов по возрастанию их зарплаты.
SELECT Name
FROM TEACHER
WHERE LOWER(Post) = 'ассистент'
ORDER BY Salary + Rise;
Если сортировка производится по столбцу или выражению, указанному в списке фразы SELECT, для указания сортируемого столбца (выражения) во фразе ORDER BY можно воспользоваться синонимом. Например, сортировку по синониму в предыдущем запросе можно указать как ORDER BY НОМЕР.
1.6.4.2 Сортировка по нескольким столбцам или выражениям Для упорядочения строк результирующей таблицы по нескольким столб-
цам следует во фразе ORDER BY привести список этих столбцов. Для каждого из них можно также указать направление сортировки и расположение строк со значениями NULL.
При упорядочении по нескольким столбцам сначала производится сорти-
ровка строк в указанном порядке по первому столбцу из списка, затем набор строк с одинаковым значением отсортированного столбца сортируется по вто-
рому столбцу и т. д.
Запрос. Вывести номера телефонов и фамилии преподавателей. Упорядо-
чить по убыванию номеров телефонов и по возрастанию фамилий.
SELECT Tel, Name
FROM TEACHER
ORDER BY Tel DESC, Name;
53
1.6.5 Итоги лекции
Усвоив материал этой лекции (урока), студенты научились:
формулировать запросы с группировкой по отдельным столбцам или выражениям;
использовать группировку по нескольким столбцам или выражениям;
задавать условия для отбора групп;
сортировать результаты запроса по отдельным столбцам и выражениям;
сортировать по нескольким столбцам и выражениям (в т.ч. отсутствую-
щим в результирующей таблице);
указывать направление сортировки.
1.7 Множественные операции над таблицами (11-12)
1.7.1 Аннотация к лекции
Рассмотренные ранее варианты предложения SELECT соответствуют не-
которым операциям реляционной алгебры, а именно — проекции, селекции
(отбору) и соединению. Кроме того, для достижения необходимой теоретико-
множественной полноты в SQL введены три дополнительные операции — объ-
единение (UNION), пересечение (INTERSECT) и разность (EXCEPT). Все они выполняются над таблицами, полученными в результате запросов, и, в свою очередь, возвращают таблицу.
1.7.2 Множественные операции в стандарте SQL
В стандарте SQL множественные операции имеют следующий синтаксис:
запрос {UNION | INTERSECT | EXCEPT } [DISTINCT | ALL] запрос
где запрос является предложением SELECT. Отличаются эти операции тем, какие строки возвращенных запросами таблиц отбираются в новую резуль-
тирующую таблицу:
UNION – все строки таблиц, возвращенных обоими запросами;
INTERSECT – только те строки, которые имеются в таблицах обоих за-
просов;
EXCEPT – только те строки таблицы первого запроса, которых нет сре-
ди строк таблицы второго запроса.
54
Запросы, содержащие множественные операторы, называются составными.
Ключевые слова ALL и DISTINCT указывают, допускаются ли в результи-
рующей таблице повторяющиеся строки.
Примечание. Отметим, что в обычных запросах при отсутствии явного указания признака уникальности предполагается использование ключевого слова ALL, а в составных запросах – DISTINCT.
Если смысл ключевого слова ALL для операции UNION интуитивно понятен (все эк-
земпляры строк результирующих таблиц запросов, в том числе одинаковые, включаются в результирующую таблицу множественной операции), то для операций INTERSECT и EXCEPT он не очевиден. В стандарте SQL для них принята следующая трактовка. Пусть,
например, обе исходные таблицы Т1 и Т2 содержат строку t, причем первая из них содержит n дубликатов t, а вторая – m дубликатов. Тогда результирующая таблица множественной операции будет содержать следующее количество дубликатов стоки t:
Tl UNION ALL T2 |
n + m |
Tl INTERSECT ALL |
T2 min(n, m) |
Tl EXCEPT ALL T2 |
max((n – m), 0) |
Такая изощренная трактовка поддерживается не во всех СУБД. Дублирование строк в результате операции объединения, как правило, допускается, но для операций пересечения и разности – запрещается. В частности, именно так работает Oracle.
Таблицы, используемые в качестве операндов множественной операции,
должны быть совместимы. Под этим подразумевается следующее:
обе таблицы должны иметь одинаковое количество столбцов;
соответствующие пары столбцов должны быть одинаковых или совме-
стимых типов.
1.7.3 Объединение таблиц
Запрос. Вывести названия факультетов и кафедр, расположенных в корпу-
се 6, а также фамилии их деканов или заведующих.
SELECT Name, Dean
FROM FACULTY
WHERE Building = '6'
UNION
SELECT Name, Head
FROM DEPARTMENT
WHERE Building = '6';
55
-------------------
NAME |
DEAN |
базы данных |
Соколов |
информатика |
Сидоров |
программирование |
Федоров |
Запрос. Вывести названия факультетов и кафедр, имеющих фонд финан-
сирования больше 25 000 (также вывести сведения о том, из какой таблицы эти данные получены).
Запрос. Вывести фамилии преподавателей с указанием категории их зар-
платы (0-500 – низкая, 500-1000 – средняя, 1000-1500 – высокая, 1500 и более – очень высокая).
SELECT Name "Фамилия", 'низкая' "Категория зарплаты"
FROM TEACHER |
WHERE Salary |
+ Rise |
<= 500 |
UNION |
'средняя' |
|
|
SELECT Name, |
+ Rise |
> 500 AND Salary + Rise <= 1000 |
|
FROM TEACHER |
WHERE Salary |
||
UNION |
'высокая' |
|
|
SELECT Name, |
+ Rise |
> 1000 AND Salary + Rise <- 1500 |
|
FROM TEACHER |
WHERE Salary |
||
UNION |
'очень высокая' |
|
|
SELECT Name, |
> 1500; |
||
FROM TEACHER |
WHERE Salary |
+ Rise |
Часто бывает полезным такое объединение двух и более запросов, в кото-
ром второй запрос (и возможные последующие запросы) добавляет в результат строки, которые не были отобраны из базовых таблиц первым запросом.
Рассмотрим пример.
Запрос. Показать фамилии кураторов групп.
SELECT SGROUP.Num Труппа". TEACHER.Name "Куратор"
FROM SGROUP, TEACHER
WHERE SGROUP.CurFK = TEACHER.TehPK;
Теперь предположим, что некоторые из групп кураторов не имеют, а также что не все преподаватели являются кураторами. В результирующей таблице та-
кие группы (в столбце Num) и преподаватели (в столбце Name) не представле-
ны. Однако нам хотелось бы, чтобы были перечислены все группы, независимо
56
от того, есть ли у них куратор, и все преподаватели, независимо от того, явля-
ются ли они кураторами.
Запрос. Показать группы и фамилии кураторов групп, включая группы, у
которых нет кураторов
SELECT SGROUP.Num "Группа", TEACHER.Name "Куратор"
FROM SGROUP, TEACHER
WHERE SGROUP.CurFK = TEACHER.TchPK
UNION
SELECT SGROUP.Num, "куратора нет"
FROM SGROUP
WHERE SGROUP.CurFK IS NULL OR
NOT SGROUP.CurFK = ANY (SELECT TchPK FROM TEACHER);
1.7.4 Пересечение таблиц
В результирующей таблице оператора INTERSECT содержатся только те строки, которые имеются в обеих исходных таблицах. Исходные таблицы за-
даются запросами, выступающими в качестве операндов этого оператора.
Запрос. Вывести факультеты, которые имеют кафедры с фондами финан-
сирования больше 26 000 и меньше 15 000.
SELECT f.Name
FROM FACULTY f. DEPARTMENT d
WHERE f.FacPK = d.FacFK AND d.Fund < 15000
INTERSECT
SELECT f.Name
FROM FACULTY f, DEPARTMENT d
WHERE f.FacPK = d.FacFK AND d.Fund > 26000;
Запрос. Вывести названия кафедр, на которых работают профессора и до-
центы.
SELECT d.Name
FROM DEPARTMENT d, TEACHER t
WHERE d.DepPK = t.DepFK AND LOWER(t.Post) = 'профессор' INTERSECT
SELECT d.Name
FROM DEPARTMENT d, TEACHER t
WHERE d.DepPK = t.DepFK AND LOWER(t.Post) = 'доцент';
57
1.7.5 Разность таблиц
Результирующая таблица оператора EXCEPT (MINUS) содержит только те строки, которые имеются в первой из исходных таблиц, но не имеются во вто-
рой. Исходные таблицы задаются запросами, выступающими в качестве опе-
рандов этого оператора.
Запрос. Вывести фамилии преподавателей, читающих лекции по дисци-
плине «базы данных», но не читающих лекции по дисциплине «операционные системы».
SELECT t.Name |
LECTURE l. SUBJECT s |
FROM TEACHER t, |
|
WHERE t.TchPK = |
l.TchFK AND l.SbjFK = s.SbjPK AND |
LOWER(s.Name) = |
'базы данных' |
EXCEPT |
|
SELECT t.Name |
LECTURE l, SUBJECT s |
FROM TEACHER t, |
|
WHERE t.TchPK = |
l.TchFK AND l.SbjFK = s.SbjPK AND |
LOWER(s.Name) = |
'операционные системы'; |
1.7.6 Дополнительные аспекты использования множественных
операций
Есть ряд вопросов, которые касаются всех множественных операций в це-
лом. Это, применение к ним группировки, использование вместе с ними сорти-
ровки, порядок выполнения множественных операций. Эти вопросы и рассмат-
риваются далее.
1.7.6.1 Множественные операции и группировка К запросам, выступающим в качестве операндов множественных операто-
ров, может применяться группировка. При этом никакие ограничения не накла-
дываются.
1.7.6.2 Множественные операции и сортировка Результаты выполнения подзапросов, выступающих в качестве операндов
множественных операций, упорядочивать запрещено. Да и нет смысла это де-
лать, так как они представляют лишь промежуточные результаты, которые пользователь не увидит. Однако результат выполнения множественной опера-
ции можно отсортировать, расположив в конце запроса фразу ORDER BY. Так
58
как не понятно, какие имена получают столбцы результирующей таблицы, сле-
дует ссылаться на них по порядковым номерам (как показано в примере).
Запрос. Указать количество принятых на работу преподавателей за 19952000 и 2000-2005 годы по различным факультетам.
SELECT f.Name, 'в 1995-2000 г. ', COUNT(*), 'принято на работу' FROM FACULTY f, DEPARTMENT d, TEACHER t
WHERE f.FacPK = d.FacFK AND d.DepPK = t.DepFK AND Hiredate BETWEEN DATE '1995-01-01' AND DATE '2000-12-31' GROUP BY f.Name
UNION ALL
SELECT f.Name, 'в 2000-2005 г. ', COUNT(*), 'принято на работу' FROM FACULTY f, DEPARTMENT d, TEACHER t
WHERE f.FacPK = d.FacFK AND d.DepPK = t.DepFK AND Hiredate BETWEEN DATE '2000-01-01' AND DATE '2005-12-31' GROUP BY f.Name
ORDER BY 1;
Обратите внимание, что стоящая в конце фраза ORDER BY относится не ко второму подзапросу, а ко всему запросу. Точно так же применяется фраза
ORDER BY и с другими множественными операторами.
Запрос. Вывести фамилии преподавателей, ведущих занятия и на 1-й, и на
2-й неделях. Результат упорядочить по фамилиям.
SELECT t.Name
FROM TEACHER t, LECTURE l
WHERE t.TchPK = l.TchFK AND l.Week = 1
INTERSECT
SELECT t.Name
FROM TEACHER t, LECTURE l
WHERE t.TchPK = l.TchFK AND l.Week = 2
ORDER BY 1;
1.7.7 Итоги лекции
Усвоив материал этой лекции, студенты научились:
формулировать запросы с объединением таблиц;
формулировать запросы с пересечением таблиц;
формулировать запросы, выражающие разность таблиц;
сортировать результаты множественных операций;
объединять результаты множественных операций.
59
1.8 Определение таблиц и представлений (13-14)
1.8.1 Аннотация к лекции
Для создания и изменения объектов базы данных используется язык опре-
деления данных — ЯОД (Data Definition Language - DDL). Ядро ЯОД образуют следующие три команды:
CREATE —создает объект базы данных;
ALTER - изменяет определение существующего объекта;
DROP — удаляет ранее созданный объект.
В реляционной базе данных таблица является основной структурной со-
ставляющей. В этом уроке мы рассмотрим создание, изменение и удаление таб-
лиц. Все это относится к самим таблицам, а не к данным, которые в них содер-
жатся.
В SQL также имеется другой вид таблиц – представления. Это виртуаль-
ные таблицы, которые актуализируются в результате выполнения указанного запроса на выборку данных. Представления будут рассмотрены в данной лек-
ции.
1.8.2 Создание таблицы
Таблицы базы данных создаются в SQL с помощью предложения CREATE TABLE, которое позволяет определить имя таблицы, столбцы таблицы и огра-
ничения целостности. Определение столбцов мы рассмотрим в этой лекции, а
ограничение целостности в одной из следующих лекций.
В минимальном варианте при создании таблицы определяется имя табли-
цы и набор имен столбцов, указанных в определенном порядке и имеющих ука-
занный тип.
Синтаксис предложения CREATE TABLE поддерживает следующую ми-
нимальную форму:
CREATE TABLE имя_таблицы (
имя_столбца тип_данных[,
имя_столбца тип_данных]...);
где тип данных должен принадлежать к одному из типов, поддерживаемых СУБД.
60