Aqui estão duas tabelas.
SCHOOL_STAFF
SCHOOL_CODE + STAFF_TYPE_NAME + LAST_UPDATE_DATE_TIME + PERSON_ID
=================================================================
ABE Principal 24-JAN-13 111222
ABE Principal 09-FEB-12 222111
PESSOAS
PERSON_ID + NAME
=================
111222 ABC
222111 XYZ
Aqui está minha consulta ao oráculo.
SELECT MAX(LAST_UPDATE_DATE_TIME) AS LAST_UPDATE, SCHOOL_CODE, PERSON_ID
FROM SCHOOL_STAFF
WHERE STAFF_TYPE_NAME='Principal'
GROUP BY SCHOOL_CODE, PERSON_ID
ORDER BY SCHOOL_CODE;
que dá este resultado
LAST_UPDATE SCHOOL_CODE PERSON_ID
===========+===========+=========
24-JAN-13 ABE 111222
09-FEB-12 ABE 222111
Eu quero selecionar o primeiro para a escola que tem data mais recente.
Obrigado.
Sua consulta atual não está dando o resultado desejado porque você está usando uma
GROUP BY
cláusula naPERSON_ID
coluna que tem um valor único para ambas as entradas. Como resultado, você retornará as duas linhas.Existem algumas maneiras de você resolver isso. Você pode usar uma subconsulta para aplicar a função de agregação para retornar o
max(LAST_UPDATE_DATE_TIME)
for eachSCHOOL_CODE
:Veja SQL Fiddle com demonstração
Ou você pode usar uma função de janela para retornar as linhas de dados para cada escola com o mais recente
LAST_UPDATE_DATE_TIME
:Veja SQL Fiddle com demonstração
Essa consulta implementa
row_number()
que atribui um número exclusivo a cada linha na partiçãoSCHOOL_CODE
e colocada em ordem decrescente com base no arquivoLAST_UPDATE_DATE_TIME
.Como nota lateral, a função JOIN com agregação não é exatamente igual à
row_number()
versão. Se você tiver duas linhas com o mesmo tempo de evento, o JOIN retornará as duas linhas, enquanto orow_number()
retornará apenas uma. Se você deseja retornar ambos com uma função de janela, considere usar arank()
função de janela, pois ela retornará laços:Ver demonstração
Estou surpreso que ninguém tenha aproveitado as funções da janela além do row_number ()
Aqui estão alguns dados para brincar:
A cláusula OVER() cria uma janela para a qual você definirá seus grupos agregados. Neste caso, estou particionando apenas no SHOOL_CODE, então veremos o FIRST_VALUE, que virá de LAST_UPDATE_DATE_TIME, agrupado por SCHOOL_CODE, e na ordem de LAST_UPDATE_DATE_TIME por ordem decrescente. Este valor será aplicado à coluna inteira para cada SCHOOL_CODE.
É importante prestar muita atenção ao seu particionamento e ordenação na cláusula over().
Devoluções:
Isso deve eliminar a maior parte da necessidade de GROUP BY e Subqueries. Você vai querer certificar-se de incluir DISTINCT.