max valores múltiples en una consulta
-
16-09-2019 - |
Pregunta
Sé que el título no suena muy descriptiva, pero es lo mejor que podía pensar en:
Tengo esta tabla
ID BDATE VALUE 28911 14/4/2009 44820 28911 17/4/2009 32240 28911 20/4/2009 30550 28911 22/4/2009 4422587,5 28911 23/4/2009 4441659 28911 24/4/2009 7749594,67 38537 17/4/2009 58280 38537 20/4/2009 137240 38537 22/4/2009 81098692 38605 14/4/2009 2722368 38605 20/4/2009 5600 38605 22/4/2009 1625400 38605 23/4/2009 6936575
que es de hecho una consulta muy complicado encapsulada en una vista, pero no es el asunto ahora.
Me gustaría tener para cada ID, la fila que contiene el más alto BDate. En este ejemplo, este sería el resultado.
ID BDATE VALUE 28911 24/4/2009 7749594,67 38537 22/4/2009 81098692 38605 23/4/2009 6936575
Ya he probado
select id, max(bdate), value from myview group by id, value
pero luego se devuelve todas las filas, ya que para cada valor collumn es diferente. Esta consulta está diseñado en Oracle v10, y soy elegible para utilizar sólo para consultas de selección y no crear procedimientos.
Solución
Podemos utilizar columnas se multiplican en una cláusula IN:
select id, bdate, value
from myview
where (id, bdate) in
(select id, max(bdate)
from myview group by id)
/
Otros consejos
puede utilizar el MAX...KEEP(DENSE_RANK FIRST...)
constructo:
SQL> SELECT ID,
2 MAX(bdate) bdate,
3 MAX(VALUE) KEEP(DENSE_RANK FIRST ORDER BY bdate DESC) VALUE
4 FROM DATA
5 GROUP BY ID;
ID BDATE VALUE
---------- ----------- ----------
28911 24/04/2009 7749594,67
38537 22/04/2009 81098692
38605 23/04/2009 6936575
Esto será tan eficiente como el método de análisis sugerido por Majkel (sin auto-unirse, una sola pasada de los datos)
Puede utilizar un INNER JOIN para filtrar sólo las filas máximas:
select t.*
from YourTable t
inner join (
select id, max(bdate) as maxbdate
from YourTable
group by id
) filter
on t.id = filter.id
and t.bdate = filter.maxbdate
Esto imprime:
id bdate value
38605 2009-04-23 6936575
38537 2009-04-22 81098692
28911 2009-04-24 7749594.67
Tenga en cuenta que esto va a devolver varias filas de un identificador que tiene múltiples valores con la misma BDate.
Puede utilizar análisis:
select
id, bdate, value
from
(
select
id, bdate, value, max( bdate ) over ( partition by id ) max_bdate
from
myview
)
where
bdate = max_bdate
select a.* from myview a, (select id, max(bdate) from myview group by id) b
where a.id = b.id and a.bdate = b.bdate
SELECT id, bdate, value FROM myview
WHERE (id, bdate) IN (SELECT id, MAX(bdate) FROM myview GROUP BY id)
(no probado ... no tengo Oracle disponible en este momento ...)