2009-09-21 130 views
1

GDAY,我有一個表,其中顯示了一系列的成績和日期時間的分數發生。 我想選擇最大的這些分數的每一天,但顯示的分數發生的日期時間。選擇按日期分組最高分,充分顯示日期時間

我使用Oracle數據庫(10克)和表的結構,如下所示:

 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) 

我不能參加比分,因爲同一個高分可能已經在一天中多次獲得。

我感謝您的幫助!

西蒙·愛德華茲

回答

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遞減的規範。

或者,您也可以做到這一點(它會列出一個日期高分的關係):

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 
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 

這可能會產生每日期的多條記錄,如果兩個不同的分數正好在同一時間發佈。

+0

謝謝大衛! 我懷疑事情會變得更加混亂,如果我想每天得到一個單獨的分數(並且將當天的最高分作爲名義上的「最大」),我將使用您提供的解決方案。乾杯。 – 2009-09-21 04:16:21

+0

@Simon:它不會更混亂,您需要在內部查詢中捕獲MAX(T.ScoreDateTime),並將該字段用作JOIN條件的一部分。很高興爲您效力! – 2009-09-21 04:36:03

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. 

Regards, Rob。