Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции_БД.doc
Скачиваний:
27
Добавлен:
04.05.2019
Размер:
4.03 Mб
Скачать
      1. Вложенные запросы.

В SQL-запросе можно использовать запросы, вложенные в первый. Это можно применить и к операторам, возвращающих совокупные характеристики, и к операторам, возвращающим множество значений.

Например,

  1. Определить всех однофамильцев в таблицах Sotrudniki и Sotrudniki1, имеющих одинаковую структуру:

SELECT * FROM Sotrudniki

WHERE S_fio IN (SELECT S_fio FROM Sotrudniki1)

- вложенный оператор SELECT возвращает множество фамилий из таблицы Sotrudniki1, а конструкция WHERE основного оператора SELECT отбирает в таблице Sotrudniki те записи, которые имеются во множестве фамилий из таблицы Sotrudniki1.

  1. Вывести из БД Sotrudniki фамилию (фамилии) самого молодого сотрудника:

SELECT S_Fio, EXTRACT(YEAR FROM S_Birthday)

FROM Sotrudniki

WHERE EXTRACT(YEAR FROM S_Birthday)=

(SELECT max(EXTRACT(YEAR FROM S_Birthday))

FROM Sotrudniki)

- вложенный оператор SELECT возвращает максимальный год рождения, который используется в условии WHERE основного оператора SELECT.

  1. Вывести из БД Students все оценки конкретного студента, например, Петрова:

SELECT S_fam, P_nazv, E_mark FROM

Examination,Predm, Students

WHERE E_student=(SELECT S_code FROM Students

WHERE S_fam='Петров')

AND E_Predm=P_code AND E_Student=S_code

  • во вложенной конструкции SELECT определяется код студента по фамилии 'Петров', а последние условия обеспечивают исключение избыточности при внутреннем объединении таблиц.

Связанные подзапросы. Во внутреннем запросе можно ссылаться на таблицу, имя которой указано в предложении FROM внешнего запроса. Такой связанный подзапрос выполняется по одному разу для каждой строки таблицы основного запроса.

Например, получить сведения о предметах, по которым проводился экзамен конкретного числа, например, ‘10.01.2006’:

SELECT * FROM Predm PR

WHERE '14.01.2006' IN (SELECT E_date

FROM Examination

WHERE PR.P_code=E_predm)

Эту же задачу можно решить с помощью операции соединения таблиц:

SELECT DISTINCT P_nazv FROM Predm, Examination

WHERE P_code=E_predm AND E_date= '14.01.2006'

Пример. Вывести фамилию (фамилии) студента, получившего на экзамене оценку выше среднего балла

SELECT DISTINCT S_fam FROM Students, Examination

WHERE

E_mark>(SELECT AVG(E_mark) FROM Examination)

AND S_code=E_student

В условии WHERE при работе с множествами записей можно использовать ключевые слова ALL и ANY. ALL - условие выполняется для всех записей, ANY - условие выполняется хотя бы для одной записи.

Например,

  1. вывести фамилии сотрудников из таблицы Sotrudniki, которые не старше любого сотрудника в таблице Sotrudniki1:

SELECT S_fio,S_birthday FROM Sotrudniki

WHERE S_birthday>= ALL (SELECT S_birthday

FROM Sotrudniki1)

  1. вывести фамилии сотрудников из таблицы Sotrudniki, которые моложе хотя бы одного сотрудника в таблице Sotrudniki1:

SELECT S_fio,S_birthday FROM Sotrudniki

WHERE S_birthday> ANY (SELECT S_birthday FROM Sotrudniki1)

Во вложенных конструкциях SELECT можно использовать ключевое слово EXISTS, которое означает отбор только тех записей, для которых вложенный запрос возвращает одно или более значений.

Например,

SELECT S_fio,S_birthday FROM Sotrudniki S1

WHERE EXISTS (SELECT S_fio,S_birthday

FROM Sotrudniki S2

WHERE (S1.S_birthday=S2.S_birthday)

AND (S1.S_code!=S2.S_code))

- получение списка сотрудников, которые имеют хотя бы одного сверстника.

Примеры.

  1. Написать запрос, выбирающий данные о фамилиях студентов, имеющих по предмету с идентификатором 2 балл ниже общего среднего балла.

SELECT DISTINCT S_fam

FROM Students, Examination

WHERE E_mark>(SELECT AVG(E_mark)

FROM Examination)

AND S_code=E_student AND E_predm=2

  1. Написать запрос, выполняющий вывод количества предметов, по которым экзаменовался каждый студент, сдававший более 2-х предметов.

SELECT COUNT(E_predm)

FROM Examination

GROUP BY E_student

HAVING COUNT (E_predm)>2

  • предложение HAVING указывает только поля или выражения, которые на выходе имеют единственное значение для каждой выводимой группы.

!!! Предложение HAVING определяет критерий, по которому группы следует включать в выходные данные, по аналогии с предложением WHERE, которое осуществляет это для отдельных строк!!!

  1. Написать запрос, который выполняет вывод а) среднего, б) минимального, в) максимального баллов всех студентов для каждой даты сдачи экзаменов и который представляет результаты в порядке убывания этих значений.

SELECT AVG(E_mark),E_date

FROM Examination

GROUP BY E_date

ORDER BY 1 DESC

SELECT MIN(E_mark),E_date

FROM Examination

GROUP BY E_date

ORDER BY 1 DESC

SELECT MAX(E_mark),E_date

FROM Examination

GROUP BY E_date

ORDER BY 1 DESC