Для дальнейшего примера внесем в данные дополнительную "кривую" строку, относящуюся с имени и дате, за которые уже есть данные:
Insert into KK_SALARY (NAME, DT, WAGE) Values ('Рябов', to_date('11.01.2012','DD.MM.YYYY'), 100501 );
Теперь познакомимся с конструкцией keep dense_rank. Выберем первую и последнюю (по дате dt) зарплату в карьере каждого сотрудника в группировке по name:
select name,
min(wage) keep (dense_rank first order by dt) first_salary_in_career_min, /*Первая зарплата за карьеру. Если на первую дату имеется несколько записей о зарплате, то взять минимальную*/
max(wage) keep (dense_rank first order by dt) first_salary_in_career_max, /*Первая зарплата за карьеру. Если на первую дату имеется несколько записей о зарплате, то взять максимальную*/
min(wage) keep (dense_rank last order by dt) last_salary_in_career_min, /*Последняя зарплата за карьеру. Если на последнюю дату имеется несколько записей о зарплате, то взять минимальную*/
max(wage) keep (dense_rank last order by dt) last_salary_in_career_max /*Последняя зарплата за карьеру. Если на последнюю дату имеется несколько записей о зарплате, то взять максимальную*/
from kk_salary
group by name;
Существует и множество других аналитических функций. Если стоит выбор между тем, чтобы просканировать таблицу несколько раз, соединив ее саму с собой ради поиска каких-то значений в ней и использованием аналитических функций, то второй способ оптимальнее.