Pregunta

Gday, tengo una tabla que muestra una serie de resultados y datetimes se produjeron esos resultados. Me gustaría seleccionar el máximo de estas puntuaciones de cada día, sino mostrar la fecha y hora en que se produjo la partitura.

Estoy utilizando una base de datos Oracle (10g) y la mesa está estructurado de esta manera:

    scoredatetime                score (integer)
    ---------------------------------------
    01-jan-09 00:10:00      10
    01-jan-09 01:00:00      11
    01-jan-09 04:00:01      9
    ...

Me gustaría ser capaz de presentar los resultados de tales lo anterior se convierte en:

 01-jan-09 01:00:00      11

Esta consulta siguiente me pone a mitad de camino .. pero no todo el camino.

select 
   trunc(t.scoredatetime), max(t.score)
from 
   mytable t
group by
   trunc(t.scoredatetime)

No puedo unir el marcador sólo porque la misma puntuación alta puede haber sido alcanzado varias veces durante el día.

Le agradezco su ayuda!

Simon Edwards

¿Fue útil?

Solución

with mytableRanked(d,scoredatetime,score,rk) as (
  select
    scoredatetime,
    score,
    row_number() over (
      partition by trunc(scoredatetime)
      order by score desc, scoredatetime desc
    )
  from mytable
)
  select
    scoredatetime,
    score
  from mytableRanked    
  where rk = 1
  order by date desc

En el caso de múltiples puntuaciones más altas dentro de un día, esto devuelve la fila correspondiente a la que se produjo la última en el día. Si quieres ver todas las calificaciones más altas en un día, eliminar scoredatetime la descripción de la orden por la especificación en la ventana row_number.

Como alternativa, puede hacer esto (aparecerá una lista de vínculos de puntuación más alta para una fecha):

select
  scoredatetime,
  score
from mytable
where not exists (
  select *
  from mytable as M2
  where trunc(M2.scoredatetime) = trunc(mytable.scoredatetime)
  and M2.score > mytable.scoredatetime
)
order by scoredatetime desc

Otros consejos

En primer lugar, aún no se ha especificado lo que debería suceder si dos o más filas dentro del mismo día contienen una alta puntuación igual.

Dos posibles respuestas a esta pregunta:

1) Sólo tienes que seleccionar una de las scoredatetime de, no importa cuál

En este caso no utilice auto une o análisis como se ve en las otras respuestas, porque hay una función de agregado especial que puede hacer su trabajo más eficiente. Un ejemplo:

SQL> create table mytable (scoredatetime,score)
  2  as
  3  select to_date('01-jan-2009 00:10:00','dd-mon-yyyy hh24:mi:ss'), 10 from dual union all
  4  select to_date('01-jan-2009 01:00:00','dd-mon-yyyy hh24:mi:ss'), 11 from dual union all
  5  select to_date('01-jan-2009 04:00:00','dd-mon-yyyy hh24:mi:ss'), 9 from dual union all
  6  select to_date('02-jan-2009 00:10:00','dd-mon-yyyy hh24:mi:ss'), 1 from dual union all
  7  select to_date('02-jan-2009 01:00:00','dd-mon-yyyy hh24:mi:ss'), 1 from dual union all
  8  select to_date('02-jan-2009 04:00:00','dd-mon-yyyy hh24:mi:ss'), 0 from dual
  9  /

Table created.

SQL> select max(scoredatetime) keep (dense_rank last order by score) scoredatetime
  2       , max(score)
  3    from mytable
  4   group by trunc(scoredatetime,'dd')
  5  /

SCOREDATETIME       MAX(SCORE)
------------------- ----------
01-01-2009 01:00:00         11
02-01-2009 01:00:00          1

2 rows selected.

2) Seleccionar todos los registros con la máxima puntuación.

En este caso es necesario análisis con un rango o función DENSE_RANK. Un ejemplo:

SQL> select scoredatetime
  2       , score
  3    from ( select scoredatetime
  4                , score
  5                , rank() over (partition by trunc(scoredatetime,'dd') order by score desc) rnk
  6             from mytable
  7         )
  8   where rnk = 1
  9  /

SCOREDATETIME            SCORE
------------------- ----------
01-01-2009 01:00:00         11
02-01-2009 00:10:00          1
02-01-2009 01:00:00          1

3 rows selected.

Saludos, Rob.

Es posible que tenga dos instrucciones SELECT para sacar esto adelante: la primera para recoger la fecha y la puntuación máxima truncada asociado, y el segundo para tirar en los valores de fecha y hora actuales relacionados con la puntuación

.

Probar:

SELECT T.ScoreDateTime, T.Score
FROM
(
 SELECT
    TRUNC(T.ScoreDateTime) ScoreDate, MAX(T.score) BestScore
 FROM 
    MyTable T
 GROUP BY 
    TRUNC(T.ScoreDateTime)
) ByDate
INNER JOIN MyTable T 
    ON TRUNC(T.ScoreDateTime) = ByDate.ScoreDate and T.Score = ByDate.BestScore
ORDER BY T.ScoreDateTime DESC

Esto hará que en mejores lazos de puntuación también.

Para obtener una versión que selecciona sólo el alto puntaje más recientemente publicado para cada día:

SELECT T.ScoreDateTime, T.Score
FROM
(
 SELECT
    TRUNC(T.ScoreDateTime) ScoreDate, 
    MAX(T.score) BestScore, 
    MAX(T.ScoreDateTime) BestScoreTime
 FROM 
    MyTable T
 GROUP BY 
    TRUNC(T.ScoreDateTime)
) ByDate
INNER JOIN MyTable T 
    ON T.ScoreDateTime = ByDate.BestScoreTime and T.Score = ByDate.BestScore
ORDER BY T.ScoreDateTime DESC

Esto puede producir múltiples registros por fecha, si dos resultados diferentes fueron publicadas exactamente al mismo tiempo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top