Sua consulta atual não está fornecendo o resultado desejado porque você está usando uma GROUP BYcláusula na PERSON_IDcoluna que possui um valor exclusivo para as duas entradas. Como resultado, você retornará as duas linhas.
Existem algumas maneiras de resolver isso. Você pode usar uma subconsulta para aplicar a função agregada para retornar o valor max(LAST_UPDATE_DATE_TIME)para cada 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;
Veja SQL Fiddle com demonstração
Ou você pode usar uma função de janelas para retornar as linhas de dados de cada escola com as mais recentes 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;
Veja SQL Fiddle com demonstração
Esta consulta implementa o row_number()que atribui um número único a cada linha na partição SCHOOL_CODEe é colocada em uma ordem decrescente com base no LAST_UPDATE_DATE_TIME.
Como uma observação lateral, o JOIN com função agregada não é exatamente o mesmo que a row_number()versão. Se você tiver duas linhas com o mesmo horário do evento, JOIN retornará as duas linhas, enquanto row_number()retornará apenas uma. Se você deseja retornar ambos com uma função de janelas, considere usar a rank()função de janelas, pois ela retornará laços:
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;
Ver demonstração