Gday,我有一张表格,显示了这些分数发生的一系列分数和日期时间。 我想为每天选择这些分数的最大值,但显示分数发生的日期时间。
我使用的是Oracle数据库(10g),表的结构如下:
scoredatetime score (integer) --------------------------------------- 01-jan-09 00:10:00 10 01-jan-09 01:00:00 11 01-jan-09 04:00:01 9 ...
我希望能够呈现上述结果:
01-jan-09 01:00:00 11
以下查询将我带到了一半......但并非一直如此。
select
trunc(t.scoredatetime), max(t.score)
from
mytable t
group by
trunc(t.scoredatetime)
我不能仅仅因为在一天中多次获得相同的高分而加入得分。
感谢您的帮助!
Simon Edwards
答案 0 :(得分:3)
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
如果一天内有多个高分,则会返回与当天最新发生的行相对应的行。如果要查看一天中的所有最高分,请在row_number窗口中按规范删除scoredatetime desc。
或者,您可以这样做(它会列出日期的高分关系):
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
答案 1 :(得分:1)
首先,如果同一天内的两行或多行包含相同的高分,您还没有指定会发生什么。
该问题的两个可能答案:
1)只需选择其中一个scoredatetime,无论哪一个
在这种情况下,不要像在其他答案中看到的那样使用自联接或分析,因为有一个特殊的聚合函数可以提高您的工作效率。一个例子:
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)选择所有具有最高分数的记录。
在这种情况下,您需要使用RANK或DENSE_RANK函数进行分析。一个例子:
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.
此致 罗布。
答案 2 :(得分:0)
您可能需要两个SELECT语句来关闭它:第一个用于收集截断日期和关联的最高分数,第二个用于提取与分数关联的实际日期时间值。
尝试:
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
这也会带来最佳分数关系。
对于每天只选择最近发布的最高分的版本:
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
如果两个不同的分数在同一时间发布,则每个日期可能产生多个记录。