Twoje obecne zapytanie nie daje pożądanego rezultatu, ponieważ używasz GROUP BYklauzuli w PERSON_IDkolumnie, która ma unikalną wartość dla obu wpisów. W rezultacie zwrócisz oba wiersze.
Istnieje kilka sposobów rozwiązania tego problemu. Za pomocą podzapytania można zastosować funkcję agregującą, aby zwrócić max(LAST_UPDATE_DATE_TIME)dla każdego 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;
Zobacz SQL Fiddle with Demo
Możesz też użyć funkcji okienkowania, aby zwrócić wiersze danych dla każdej szkoły z najnowszymi 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;
Zobacz SQL Fiddle with Demo
To zapytanie implementuje, row_number()który przypisuje unikalny numer do każdego wiersza w partycji SCHOOL_CODEi umieszczony w kolejności malejącej na podstawie LAST_UPDATE_DATE_TIME.
Na marginesie, JOIN z funkcją agregującą nie jest dokładnie taki sam jak row_number()wersja. Jeśli masz dwa wiersze z tym samym czasem zdarzenia, JOIN zwróci oba wiersze, a row_number()tylko jeden zwróci. Jeśli chcesz zwrócić oba z funkcją okienkowania, rozważ użycie rank()funkcji okienkowania, ponieważ zwróci ona więzi:
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;
Zobacz demo