Ваш текущий запрос не дает желаемого результата, потому что вы используете GROUP BY
предложение для PERSON_ID
столбца, которое имеет уникальное значение для обеих записей. В результате вы вернете обе строки.
Есть несколько способов, которые вы можете решить это. Вы можете использовать подзапрос, чтобы применить агрегатную функцию, возвращающую max(LAST_UPDATE_DATE_TIME)
для каждого SCHOOL_CODE
:
select s1.LAST_UPDATE_DATE_TIME,
s1.SCHOOL_CODE,
s1.PERSON_ID
from SCHOOL_STAFF s1
inner join
(
select max(LAST_UPDATE_DATE_TIME) LAST_UPDATE_DATE_TIME,
SCHOOL_CODE
from SCHOOL_STAFF
group by SCHOOL_CODE
) s2
on s1.SCHOOL_CODE = s2.SCHOOL_CODE
and s1.LAST_UPDATE_DATE_TIME = s2.LAST_UPDATE_DATE_TIME;
Смотрите SQL Fiddle с демо
Или вы можете использовать оконную функцию для возврата строк данных для каждой школы с самыми последними LAST_UPDATE_DATE_TIME
:
select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
from
(
select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
row_number() over(partition by SCHOOL_CODE
order by LAST_UPDATE_DATE_TIME desc) seq
from SCHOOL_STAFF
where STAFF_TYPE_NAME='Principal'
) d
where seq = 1;
Смотрите SQL Fiddle с демо
Этот запрос реализует, row_number()
который присваивает уникальный номер каждой строке в разделе SCHOOL_CODE
и размещается в порядке убывания на основе LAST_UPDATE_DATE_TIME
.
В качестве примечания, JOIN с агрегатной функцией не совсем совпадает с row_number()
версией. Если у вас есть две строки с одним и тем же временем события, JOIN вернет обе строки, а row_number()
только одну. Если вы хотите вернуть оба с помощью функции управления окнами, рассмотрите возможность использования rank()
функции управления окнами, поскольку она будет возвращать связи:
select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME
from
(
select SCHOOL_CODE, PERSON_ID, LAST_UPDATE_DATE_TIME,
rank() over(partition by SCHOOL_CODE
order by LAST_UPDATE_DATE_TIME desc) seq
from SCHOOL_STAFF
where STAFF_TYPE_NAME='Principal'
) d
where seq = 1;
Посмотреть демо