Три манифеста баз данных ретроспектива и перспективы



         

Полиморфизм - часть 2


Наличие полной ортогональности правил композиции в OQL позволяет не ограничивать мощность выражений и облегчить общее понимание языка, сохраняя возможность использования SQL -подобного синтаксиса при формулировке наиболее простых запросов.

Среди операций, которые поддерживаются в OQL и еще не упоминались в этом разделе, содержатся “множественные” операции union , intersect и except для всех видов коллекций; операции с кванторами for all и exists ; операции сортировки и группирования (sort и group by ); агрегатные операции count , sum , min , max и avg . Мы не будем подробно обсуждать эти операции47, но приведем пример достаточно сложного запроса, в котором некоторые из операций используются.

Пример 2.15. Найти название отдела, в котором работают служащие, средняя зарплата которых меньше средней зарплаты служащих любого другого отдела (для простоты предположим, что размер средней зарплаты служащих во всех отделах различается).

Будем строить запрос по шагам с использованием конструкции языка OQL define для вычисления промежуточных результатов.

Шаг 1. Построить множество объектов-служащих, для которых известен номер отдела.

define EMPLOYEES_D () AS
     SELECT E FROM EMPLOYEES E
     WHERE E.WORKS IS NOT nil

Шаг 2. Сгруппировать служащих с известными номерами отделов по номерам отделов и вычислить размер средней зарплаты для каждого отдела.

DEFINE DEPT_AVG_SAL () AS
     SELECT DEPT_NO,
            AVG_SAL : avg (SELECT X.E.EMP_SAL FROM PARTITION X )
     FROM EMPLOYEES_D () E
     GROUP BY DEPT_NO : E.DEPT_NO

Типомрезультатаэтогозапросаявляетсяbag < struct { integer DEPT_NO; decimal AVG_SAL } > . Операция group by расщепляет множество служащих на разделы (partitions ) в соответствии с критерием группирования (номеру отдела, в котором работает служащий). В разделе SELECT для каждого раздела вычисляется размер средней зарплаты сотрудников.

Шаг 3. Отсортировать полученное мультимножество по значениям атрибута AVG _ SAL .

DEFINE SORTED_DEPT_AVG_SAL () AS
     SELECT S FROM DEPT_AVG_SAL () AS S ORDER BY S.AVG_SAL

Типомрезультатаявляетсяlist < struct { integer DEPT_NO; decimal AVG_SAL } > .

Шаг 4. Выбрать значение атрибута DEPT _ NO из элемента списка SORTED _ DEPT _ AVG _ SAL с наименьшим значением AVG _ SAL (этот элемент стоит в списке первым).

FIRST (SORTED_DEPT_AVG_SAL ()).DEPT_NO

Если собрать запрос целиком, то мы получим следующую конструкцию:

FIRST (SELECT DEPT_NO,
              AVG_SAL : avg (SELECT X.E.EMP_SAL FROM PARTITION X )
          FROM (SELECT E FROM EMPLOYEES E
                     WHERE E.WORKS IS NOT nil) AS E
          GROUP BY DEPT_NO : E.DEPT_NO
          ORDER BY AVG_SAL).DEPT_NO




Содержание  Назад  Вперед