logo
Лабы базы Данных / Базы данных / Введение в модель данных SQL

Предикаты сравнения с квантором

SELECT DEPT_NO, AVG (CURRENT_DATE - EMP_BDATE)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO

HAVING AVG (CURRENT_DATE - EMP_BDATE)< SOME

(SELECT AVG (CURRENT_DATE - EMP1.EMP_BDATE)

FROM EMP EMP1

WHERE EMP1.DEPT_NO IS NOT NULL

GROUP BY EMP1.DEPT_NO);

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

Напомним, что "ниладическая" функция CURRENT_DATE выдает текущую дату, и, следовательно, значением выражения CURRENT_DATE - EMP_BDATE является интервал, представляющий текущий возраст сотрудника. На наш взгляд, формулировка этого запроса несколько упрощается, если пользоваться предикат предикатом EXISTS (пример 15.11.1):

SELECT DEPT_NO, AVG (CURRENT_DATE - EMP_BDATE)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO

HAVING EXISTS (SELECT EMP1.DEPT_NO

FROM EMP EMP1

WHERE EMP1.DEPT_NO IS NOT NULL

GROUP BY EMP1.DEPT_NO

HAVING AVG (CURRENT_DATE - EMP1.EMP_BDATE) >

AVG (CURRENT_DATE - EMP.EMP_BDATE));

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

SELECT DEPT_NO, AVG (CURRENT_DATE - EMP_BDATE)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO

HAVING AVG (CURRENT_DATE - EMP_BDATE) <= ALL

(SELECT AVG (CURRENT_DATE - EMP_BDATE)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO);

Пример 15.12. Найти номера отделов и средний возраст сотрудников для отделов с минимальным средним возрастом сотрудников. (html,txt)

Этот запрос легко формулируется в более понятном виде с использованием предиката NOT EXISTS (пример 15.12.1):

SELECT DEPT_NO, AVG (CURRENT_DATE - EMP_BDATE)

FROM EMP

WHERE DEPT_NO IS NOT NULL

GROUP BY DEPT_NO

HAVING NOT EXISTS (SELECT EMP1.DEPT_NO

FROM EMP EMP1

WHERE EMP1.DEPT_NO IS NOT NULL

GROUP BY EMP1.DEPT_NO

HAVING AVG (CURRENT_DATE - EMP1.EMP_BDATE) <

AVG (CURRENT_DATE - EMP.EMP_BDATE));

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