SQL仅选择每个用户中具有最大日期的行

时间:2015-03-23 19:11:00

标签: sql oracle date subquery greatest-n-per-group

SQL初学者在这里。我有一个用户采取的简单测试,每一行都是他们的一个问题的答案。他们每天允许参加一次考试,所以有些人会在另一天再次参加考试,因此会有很多行具有不同的考试日期。我基本上要做的就是让每个用户获得最新的分数。

这是我的数据的样子(表名是dumdum):

+----------+----------------+----------+------------------+
| USERNAME | CORRECT_ANSWER | RESPONSE | DATE_TAKEN       |
+----------+----------------+----------+------------------+
| matt     | 1              | 1        | 3/23/15 1:04:26  |
| matt     | 2              | 2        | 3/23/15 1:04:28  |
| matt     | 3              | 3        | 3/23/15 1:04:23  |
| david    | 1              | 3        | 3/20/15 1:04:25  |
| david    | 2              | 2        | 3/20/15 1:04:28  |
| david    | 3              | 1        | 3/20/15 1:04:30  |
| david    | 1              | 1        | 3/21/15 11:03:14 |
| david    | 2              | 3        | 3/21/15 11:03:17 |
| david    | 3              | 2        | 3/21/15 11:03:19 |
| chris    | 1              | 2        | 3/17/15 12:45:52 |
| chris    | 2              | 2        | 3/17/15 12:45:56 |
| chris    | 3              | 3        | 3/17/15 12:45:59 |
| peter    | 1              | 1        | 3/19/15 2:45:33  |
| peter    | 2              | 3        | 3/19/15 2:45:35  |
| peter    | 3              | 2        | 3/19/15 2:45:38  |
| peter    | 1              | 1        | 3/20/15 12:32:04 |
| peter    | 2              | 2        | 3/20/15 12:32:05 |
| peter    | 3              | 3        | 3/20/15 12:32:05 |
+----------+----------------+----------+------------------+

以及我最终要做的事情......

+----------+------------------+-------+
| USERNAME | MOST_RECENT_TEST | SCORE |
+----------+------------------+-------+
| matt     | 3/23/2015        | 100   |
| david    | 3/21/2015        | 33    |
| chris    | 3/17/2015        | 67    |
| peter    | 3/20/2015        | 100   |
+----------+------------------+-------+

我遇到了一些麻烦,因为我需要白天去,而不是白天/时间,所以我不得不做一个奇怪的动作,我去了角色并回到过去......这就是我到目前为止所拥有的,但我无法弄清楚如何只使用最近测试的分数(现在它考虑了每次测试的所有分数)......

SELECT username, to_date(substr(max(test_date),1,9),'dd-MON-yy') as most_recent_test, round((sum(case when response=correct_answer then 1 end)/3)*100,0) as score
FROM dumdum group by username

任何帮助将不胜感激!谢谢!

1 个答案:

答案 0 :(得分:3)

这个问题有几个解决方案,这个解决方案使用WITH子句和RANK函数。

它还使用TRUNC函数而不是to_date(substr(

 with mxDate as 
 (SELECT USERNAME,
        TRUNC(DATE_TAKEN) as MOST_RECENT_TEST,
        CASE WHEN CORRECT_ANSWER = RESPONSE THEN 1 else 0 END as SCORE,
        RANK () OVER (PARTITION BY  USERNAME
                           ORDER BY TRUNC(DATE_TAKEN)  DESC) Rk
 FROM dumdum)
SELECT
   USERNAME,
   MOST_RECENT_TEST,
   SUM(SCORE)/3 * 100

FROM
   mxDate 
WHERE 
  rk = 1
GROUP BY 
   USERNAME,
   MOST_RECENT_TEST

Demo