Twoje obecne zapytanie nie daje pożądanego rezultatu, ponieważ używasz GROUP BY
klauzuli w PERSON_ID
kolumnie, 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_CODE
i 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