Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабы базы Данных / Базы данных / Введение в модель данных SQL.doc
Скачиваний:
83
Добавлен:
22.03.2015
Размер:
1.93 Mб
Скачать

Предикат between

SELECT DEPT_NO, MIN(EMP_SAL), MAX(EMP_SAL)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO

HAVING AVG(EMP_SAL) BETWEEN

(SELECT AVG(EMP_SAL)

FROM EMP) AND 30000.00;

Пример 15.5. Найти номера отделов и минимальный и максимальный размер зарплаты сотрудников для отделов, в которых средний размер зарплаты сотрудников не меньше среднего размера зарплаты сотрудников во всей компании и не больше 30000 руб. (html,txt)

Еще раз приведем возможную формулировку этого запроса без использования разделов GROUP BY и HAVING (пример 15.5.1):

SELECT DISTINCT DEPT_NO, (SELECT MIN(EMP1.EMP_SAL)

FROM EMP EMP1

WHERE EMP1.DEPT_NO = EMP.DEPT_NO),

(SELECT MAX(EMP1.EMP_SAL)

FROM EMP EMP1

WHERE EMP1.DEPT_NO = EMP.DEPT_NO)

FROM EMP

WHERE (SELECT AVG(EMP1.EMP_SAL)

FROM EMP EMP1

WHERE EMP1.DEPT_NO = EMP.DEPT_NO) BETWEEN

(SELECT AVG(EMP_SAL)

FROM EMP) AND 30000.00;

Пример 15.5.1. (html,txt)

Как видно, отказ от использования раздела GROUP BY приводит к размножению однотипных подзапросов, в каждом из которых строится одна и та же группа строк, над которой вычисляется агрегатная функция.

Предикат null

SELECT DEPT.DEPT_NO, COUNT(*)

FROM DEPT, EMP EMP1, EMP EMP2

WHERE DEPT.DEPT_NO = EMP2.DEPT_NO

AND DEPT.DEPT_MNG = EMP1.EMP_NO

GROUP BY DEPT.DEPT_NO, EMP1.DEPT_NO

HAVING EMP1.DEPT_NO IS NULL;

Пример 15.6. Найти номера и число сотрудников отделов, данные о руководителях которых не содержат номер отдела (конечно, в этом случае нас интересуют только те отделы, у которых имеется руководитель). (html,txt)

Как и в примере 15.4, условие раздела HAVING можно переместить в раздел WHERE и получить вторую формулировку (пример 15.6.1):

SELECT DEPT.DEPT_NO, COUNT(*)

FROM DEPT, EMP EMP1, EMP EMP2

WHERE DEPT.DEPT_NO = EMP2.DEPT_NO AND

DEPT.DEPT_MNG = EMP1.EMP_NO AND

EMP1.DEPT_NO IS NULL

GROUP BY DEPT.DEPT_NO;

Пример 15.6.1. (html,txt)

Кстати, в этом случае, поскольку в запросе присутствует только один вызов агрегатной функции, формулировка без использования раздела GROUP BY оказывается более понятной и не менее эффективной (даже при следовании предписанной семантике выполнения оператора SELECT), что показывает пример 15.6.2:

SELECT DEPT.DEPT_NO, (SELECT COUNT(*)

FROM EMP

WHERE DEPT.DEPT_NO = EMP.DEPT_NO)

FROM DEPT, EMP

WHERE DEPT.DEPT_MNG = EMP.EMP_NO AND

EMP.DEPT_NO IS NULL;

Пример 15.6.2. (html, txt)

Предикат in

SELECT DEPT.DEPT_NO

FROM DEPT, EMP

WHERE DEPT.DEPT_NO = EMP.DEPT_NO

GROUP BY DEPT.DEPT_NO

HAVING AVG(EMP.EMP_SAL) IN

(SELECT MAX(EMP1.EMP_SAL)

FROM EMP, DEPT DEPT1

WHERE EMP.DEPT_NO = DEPT1.DEPT_NO

AND DEPT1.DEPT_NO <> DEPT.DEPT_NO

GROUP BY DEPT.DEPT_NO);

Пример 15.7. Найти номера отделов, в которых средний размер зарплаты сотрудников равен максимальному размеру зарплаты сотрудников какого-либо другого отдела. (html,txt)

Этот запрос, помимо прочего, демонстрирует наличие в условии раздела HAVING вложенного подзапроса с корреляцией. Как и раньше, можно избавиться от разделов GROUP BY и HAVING во внешнем запросе (пример 15.7.1):

SELECT DEPT.DEPT_NO

FROM DEPT

WHERE (SELECT AVG(EMP_SAL)

FROM EMP

WHERE EMP.DEPT_NO = DEPT.DEPT_NO) IN

(SELECT MAX(EMP1.EMP_SAL)

FROM EMP, DEPT DEPT1

WHERE EMP.DEPT_NO = DEPT1.DEPT_NO

AND DEPT1.DEPT_NO <> DEPT.DEPT_NO

GROUP BY DEPT.DEPT_NO);

Пример 15.7.1. (html,txt)

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

Соседние файлы в папке Базы данных