Весьма замысловатые функции. Полагаю, применяться будут редко.
Пишу для информации.
Первое:
Текст примера запроса, который содержится в документации не совсем точен, он не помогает понять, как это работает.
http://docs.oracle.com/cd/E11882_01/server.112/e10592/functions065.htm
А именно, если исключить в первом запросе обе фразы
KEEP (DENSE_RANK FIRST ORDER BY commission_pct)
то результат выполнения запроса не меняется.
Правильно так (здесь слово last исправлено на first):
select DEPARTMENT_ID
, min (SALARY) keep (dense_rank first order by COMMISSION_PCT) "Worst"
, max (SALARY) keep (dense_rank first order by COMMISSION_PCT) "Best"
from HR.EMPLOYEES
group by DEPARTMENT_ID
order by DEPARTMENT_ID, "Worst", "Best";
select DEPARTMENT_ID, COMMISSION_PCT, SALARY
from HR.EMPLOYEES
order by
DEPARTMENT_ID, COMMISSION_PCT
Первый запрос из документации работает так:
- Каждый департамент обсчитывается независимо, благодаря group by DEPARTMENT_ID
- Здесь будем смотреть только департамент 80, поскольку только у него ненулевые COMMISSION_PCT
- В пределах департамента 80 строки сортируются по COMMISSION_PCT. Определяется минимальное значение этого поля (иным словами применяется функция аналитическая функция DENSE_RANK). Это фраза dense_rank first order by COMMISSION_PCT
- Для всех строк в группе DEPARTMENT_ID, которые обладают этим минимальным значением COMMISSION_PCT рассчитывается min (SALARY)
- Рассчитанное значение распространяется на все строки группы DEPARTMENT_ID
Зеленым фоном выделил то, что делает фраза после KEEP
Что хотел сказать вендор разработкой этой функции, сказать трудно, пока вижу такие варианты:
Во первых, вместо SUM можно подставить любую агрегатную функцию.
Во вторых, подставив например COUNT и LAST получим количество людей в департаменте, которые обладают максимальной COMMISSION_PCT (премией с продаж) относительно общей численности департамента -- поделите / вычтите общий COUNT
Аналитическая форма работает схожим образом. GROUP BY не используется, а группировочное выражение пишется в фразу PARTITION BY