- •Введение
- •Лабораторное занятие № 1
- •Описание учебного примера.
- •Удаление таблиц
- •Создание таблиц
- •Имена ограничений
- •Ограничения null и not null
- •Ограничение primary key
- •Ограничение unique
- •Ограничение Foreign key
- •Ограничение check
- •Вопросы для самоконтроля к лабораторной работе № 1
- •Лабораторная работа № 2
- •Команда вставки - insert
- •Команда обновления - update
- •Команда удаления - delete
- •Вопросы для самоконтроля к лабораторной работе № 2
- •Лабораторная работа №3
- •Команда alter table
- •Модификация ограничений
- •Добавление ограничений с ограниченной областью проверки
- •Отключение и подключение ограничений
- •Правила для изменения и модификации описания столбцов
- •Добавление столбца
- •Модификация столбца
- •Удаление столбца
- •Удаление таблицы
- •Переименование таблицы
- •Вопросы для самоконтроля к лабораторной работе № 3
- •Лабораторная работа № 4
- •Выборка данных из нескольких таблиц
- •Определение условий выборки в предложении where.
- •Групповые функции и предложение group by
- •Наиболее часто встречающиеся ошибки при выполнении group by
- •Предложение order by
- •Вопросы для самоконтроля к лабораторной работе № 4
- •Лабораторная работа № 5
- •Подзапросы
- •Вопросы для самоконтроля к лабораторной работе № 5
- •Лабораторная работа №6
- •Представления
- •Вопросы для самоконтроля к лабораторной работе № 6
- •Лабораторная работа №7
- •Хранимые процедуры
- •Оператор use
- •Оператор declare
- •Операторы set и select
- •Функция @@identity
- •Функция @@error
- •Объявление параметров
- •Изменение хранимых процедур
- •Удаление хранимой процедуры
- •Лабораторная работа №8
- •Вопросы для самоконтроля к лабораторной работе № 8
- •Задания в тестовой форме
- •Литература Оглавление
Лабораторная работа № 5
Цель занятия: Изучить классификацию подзапросов и правила их формирования.
Подзапросы
П
одзапрос
– это команда SELECT, вложенная в предложение
другой команды SQL. Подзапросы могут
использоваться в командах SELECT, UPDATE,
INSERT, DELETE, CREATE TABLE. Например, каждая команда
SELECT может включать в себя несколько
других команд SELECT6.
При этом подзапрос (внутренний запрос)
генерирует значение, которое проверяется
в предикате внешнего запроса. Подзапросы
всегда выполняются от внутренних к
внешнему, если только не являются
коррелированными. Подзапрос может
возвращать одну и более строк или один
и более столбцов.
Подзапрос помещается в круглые скобки и должен стоять в правой части оператора сравнения внешнего запроса.
Подзапрос может обращаться к таблицам отличным от тех, к которым обращается основной запрос.
Подзапрос может задаваться в сложных критериях поиска внешних запросов с использованием логических связок AND и OR.
Предложение ORDER BY ставится последним в основном запросе и не может содержаться в подзапросе.
В команде SELECT подзапрос может стоять в предложениях FROM, WHERE, HAVING.
Подзапрос может содержать группы и групповые функции.
Имена столбцов в предложении SELECT внутреннего запроса должны стоять в той же последовательности, что и имена столбцов в левой части оператора сравнения внешнего запроса. Типы столбцов должны попарно соответствовать.
В критерии поиска могут использоваться логические операторы, операторы ANY (SOME), ALL.
Подзапрос на уровне предложения WHERE
Пример 69
Задача.
Вывести имена студентов и их оценки, если оценка меньше средней по университету.
Решение.
SELECT StName, Mark
FROM Student S,Progress P
WHERE S.NRecordBook=P. NRecordBook
AND Mark<(SELECT AVG(Mark)
FROM Progress)
Результат реализации запроса:
Подзапрос вычисляет среднюю оценку и подставляет высчитанное значение в предложение WHERE внешнего запроса.
Коррелированные подзапросы на уровне предложения WHERE
Коррелированные подзапросы – это вложенные подзапросы. Они выполняются для каждой строки главного запроса.
Последовательность выполнения коррелированного подзапроса:
внешний запрос выбирает строку;
выполняется внутренний запрос, используя значение строки внешнего запроса;
результат выполнения внутреннего запроса возвращается во внешний запрос, где проверяется его соответствие выбранной строке;
выбирается следующая строка внешнего запроса.
При задании вложенных запросов допускаются применение операторов АNY, EXISTS, ALL и логических операторов.
Пример 70
Задача.
Вывести имена студентов, чьи оценки выше, чем средняя оценка в их группе.
Решение:
SELECT StName,Mark
FROM Student s,Progress p
WHERE S.NRecordBook=P.NRecordBook
AND Mark>(SELECT AVG(Mark)
FROM Progress P1,Student S1
WHERE S1.IDGroup=S.IDGroup
AND S1.NRecordBook=P1.NRecordBook)
Результат реализации запроса:
Рисунок 2
Из примера становится очевидным, что коррелированные запросы следует применять только в случае крайней необходимости, так как производительность их мала. Например, при реализации запроса средняя оценка по группе вычисляется столько раз, сколько раз информация о группе встречается в первом запросе. Далее (см. Пример 75) приведен пример использования коррелированного подзапроса в команде UPDATE.
Задание 22
Вывести имя студента, название предмета и оценку студентов для тех студентов, у которых оценка по той или иной дисциплине выше средней оценки по этой самой дисциплине.
Задание 23
Вывести имя студента, название предмета и оценку студентов для тех студентов, у которых оценка по той или иной дисциплине выше средней оценки по группе, в которой они обучаются.
Задание 24
Вывести имена студентов, у которых средняя оценка равна средней оценке по группе, в которой учится студент.
Подзапрос на уровне предложения HAVING
Пример 71
Задача.
Вывести имена студентов, у которых средняя оценка, выше средней по университету.
Решение.
Было бы ошибочно использовать следующий синтаксис команды. Выше уже говорилось о том, что отбор групп по условию возможен только в предложении HAVING.
SELECT StName, AVG(Mark)
FROM Student s,Progress p
WHERE s.NRecordBook =p. NRecordBook
AND AVG(Mark) >(SELECT AVG(Mark)
FROM Progress)
GROUP BY StName
Результат реализации запроса:
Server: Msg 147
An aggregate may not appear in the WHERE clause unless it is in a subquery contained in a HAVING clause or a select list, and the column being aggregated is an outer reference.
Корректный синтаксис команды будет следующим:
SELECT StName, AVG(Mark)
FROM Student s,Progress p
WHERE s.NRecordBook =p. NRecordBook
GROUP BY StName
HAVING AVG(Mark) >(SELECT AVG(Mark)
FROM Progress)
Результат реализации запроса:
Наибольшее затруднение, как ни странно, вызывают функции по работе с датами, поэтому ниже мы приводим наиболее употребимые функции (см. Приложение 4. Функции обработки дат и Приложение 5. Допустимые значения параметра частьДаты).
Пример 72
Задача.
Вывести год, в котором было принято на работу наибольшее число сотрудников.
Решение:
select year(DateHire)
from Teacher
group by year (DateHire)
having count(year (DateHire))=(select max(d.aCount)
from (select count (year (DateHire)) aCount
from Teacher
group by(year (DateHire))) d)
Результат реализации запроса:
Подзапрос на уровне предложения FROM
В ряде случаев нам надо сравнить результаты агрегирования строк. Выше был приведен пример коррелированного запроса, осуществляющего вывод имен студентов, которые имели оценки выше, чем средняя оценка по той группе, в которой они учатся (см. Пример 70). Применение подзапроса на уровне FROM позволяет значительно упростить реализацию этого запроса (см. Пример 73).
Пример 73
Задача.
Вывести имена студентов, чьи оценки выше, чем средняя оценка в их группе.
Решение:
SELECT S.StName,S.NRecordBook
FROM Progress P
INNER JOIN Student S
on P.NRecordBook=S.NRecordBook
INNER JOIN
(SELECT IDGroup,AVG(Mark) BMark
FROM Progress P
INNER JOIN Student S
on P.NRecordBook=S.NRecordBook
GROUP BY IDGroup) b
ON S.IDGroup=b.IDGroup
WHERE mark>BMark
Результат реализации запроса:
Пример 74
Задача.
Вывести имена студентов, чьи средние оценки равны средней оценке в их группе.
Решение:
SELECT a.StName,a.NRecordBook,Amark,Bmark
FROM (SELECT p.NRecordBook,StName,IDGroup,AVG(Mark) Amark
FROM Progress P
INNER JOIN Student s
ON P.NRecordBook=S.NRecordBook
GROUP BY P.NrecordBook,StName,IDGroup) a
INNER JOIN
(SELECT IDGroup,AVG(Mark) Bmark
FROM Progress P
INNER JOIN Student s
on P.NRecordBook=S.NRecordBook
GROUP BY IDGroup) b
ON a.IDGroup=b.IDGroup
WHERE Amark=Bmark
Результат реализации запроса:
Задание 25
Вывести имена студентов отличников и название предметов, по которым они сдавали экзамены.
Задание 26
Вывести все названия видов отчетности и названия дисциплин по тем дисциплинам, по которым не было получено ни одной отличной оценки.
Подзапрос в команде INSERT
Задача.
Добавить в таблицу Student записи из таблицы Student1.
Решение:
INSERT INTO Student
SELECT NRecordBook, Sname, CodeGroup
FROM Student1;
Или, если порядок столбцов в обеих таблицах одинаковый,
INSERT INTO Student
SELECT *
FROM Student_1;
Подзапрос в команде UPDATE
Пример 75
Задача.
Внести в столбец MarkAVG таблицы Student среднюю оценку студента. Предварительно нужно создать такой столбец в таблице Student с помощью команды:
alter table Student
add MarkAVG decimal(3,2)
Решение:
UPDATE Student
SET MarkAVG =
(SELECT AVG(Mark)
FROM Progress
GROUP BY NRecordBook
HAVING Student. NRecordBook= Progress. NRecordBook) ;
Просмотрим результат с помощью запроса:
Select StName ФИО, MarkAVG [Средняя оценка]
from Student
Результат реализации запроса:
Подзапрос в команде DELETE
Пример 76
Задача.
Удалить из таблицы Student студентов тех групп, которые встречаются в таблице Progress меньше 5 раз.
Решение:
DELETE FROM Student
WHERE IDGroup IN
(SELECT IDGroup
FROM Progress Pr, Student St
WHERE Pr. NRecordBook= St .NRecordBook
GROUP BY IDGroup
HAVING Count(IDGroup)< 5 ) ;
Объединение двух или более запросов с помощью UNION
UNION – специальный оператор, с помощью которого можно из двух или более запросов построить единое результирующее множество, т.е. выходные данные одного запроса присоединяются к выходным данным другого запроса.
Основные правила при реализации операций над множествами
запросы, соединяемые оператором UNION должны иметь одинаковое количество столбцов в предложении SELECT;
возвращаемый комбинированный результат будет иметь заголовки столбцов первого предложения SELECT;
тип данных каждого столбца должен быть совместим с типом данных соответствующего столбца другого запроса;
по умолчанию режимом вывода для UNION является DISTINCT.
Пример 77
Задача.
Получить все записи о студентах, фамилии которых начинаются на букву 'М' или 'И'.
Решение.
SELECT NRecordBook,StName
FROM Student
WHERE SUBSTRING(StName,1,1)= 'М'
UNION
SELECT NRecordBook,StName
FROM Student
WHERE SUBSTRING7(StName,1,1)= 'И'
Результат выполнения запроса.
Результатом выполнения этой операции будет вывод только уникальных имен студентов, ни одно имя не будет повторено дважды.
select StName
FROM Student
WHERE StName='Иванов И.И.'
UNION all
select StName
FROM Student
WHERE SUBSTRING(NRecordBook,6,1)='1'
После выполнения операции UNION ALL каждое имя будет выведено столько раз, сколько раз оно встречается в запросах.
Результат выполнения запроса.
Предложение ORDER BY в операциях над множествами может стоять только в последнем предложении запроса, при этом вместо имен столбцов используются их номера из предложения SELECT.
Пример 78
Задача.
Вывести всех студентов, у которых есть или отличные или хорошие оценки.
Решение.
SELECT StName ФИО, Mark Оценка
FROM Student s, Progress p
WHERE s.NRecordBook=p.NRecordBook
AND Mark=5
UNION
SELECT StName,Mark
FROM Student s,Progress p
WHERE s.NRecordBook=p.NRecordBook
AND Mark=4
ORDER BY 1
Результат выполнения запроса.
Задание 27
Используя операторы над множествами, вывести имена всех студентов, которые сдали экзамен по дисциплине Проектирование баз данных или по дисциплине Организация баз данных.
