mysql - 为每个用户选择每天最高的 3 个分数

标签 mysql

我有一个像这样的 MYSQL 表:

  id |  userid  |  score  |      datestamp      |
-----------------------------------------------------
  1  |    1     |   5     |  2012-12-06 03:55:16
  2  |    2     |   0,5   |  2012-12-06 04:25:21
  3  |    1     |   7     |  2012-12-06 04:35:33
  4  |    3     |   12    |  2012-12-06 04:55:45
  5  |    2     |   22    |  2012-12-06 05:25:11
  6  |    1     |   16,5  |  2012-12-06 05:55:21
  7  |    1     |   19    |  2012-12-06 13:55:16
  8  |    2     |   8,5   |  2012-12-07 06:27:16
  9  |    2     |   7,5   |  2012-12-07 08:33:16
  10 |    1     |   10    |  2012-12-07 09:25:19
  11 |    1     |   6,5   |  2012-12-07 13:33:16
  12 |    3     |   6     |  2012-12-07 15:45:44
  13 |    2     |   4     |  2012-12-07 16:05:16
  14 |    2     |   34    |  2012-12-07 18:33:55
  15 |    2     |   22    |  2012-12-07 18:42:11

我想像这样显示用户分数: 如果某个用户在某一天的得分超过 3 个,它只会获得最高的 3 个,每天为该用户重复该操作,然后将所有天数加在一起。我想为每个用户显示这个总和。

编辑: 因此,在上面的示例中,用户 1 在 06.12 上。我会将前 3 名得分加在一起并忽略第 4 名得分,然后从第二天开始将前 3 名加到该数字上,依此类推。我需要每个用户的那个号码。

编辑 2: 预期输出是:

  userid |   score  
--------------------
    1    |    59    //19 + 16.5 + 7 (06.12.) + 10 + 6.5 (07.12.)
    2    |    87    //22 + 0.5 (06.12.) + 34 + 22 + 8.5 (07.12.)
    3    |    18    //12 (06.12.) + 6 (07.12.)

我希望这更清楚:)

我真的很感激你的帮助,因为我被困住了。

最佳答案

请看下面的代码,如果你对我的评论的回答是yes :) 因为你的数据都是 2012 年的,而且是 11 月份,我花了一天。

查询:

select y.id, y.userid, y.score, y.datestamp 
from (select id, userid, score, datestamp 
      from scores
      group by day(datestamp)) as y    
where (select count(*) 
       from (select id, userid, score, datestamp
             from scores group by day(datestamp)) as x
       where y.score >= x.score
       and y.userid = x.userid
      ) =1 -- Top 3rd, 2nd, 1st    
order by y.score desc
;

结果:

ID  USERID  SCORE   DATESTAMP
8   2       8.5 December, 07 2012 00:00:00+0000
20  3       6   December, 08 2012 00:00:00+0000
1   1       5   December, 06 2012 00:00:00+0000

基于您对问题的最新更新。 如果您需要按年/月/日对每个用户进行一些查询,然后找到最高的,您可以简单地在上面的查询中添加像 sum 这样的聚合函数。我正在重复自己,因为你的样本数据只有一年,所以没有按年或按月的点组。这就是我休息一天的原因。

select y.id, y.userid, y.score, y.datestamp 
from (select id, userid, sum(score) as score,
      datestamp 
from scores
group by userid, day(datestamp)) as y    
where (select count(*) 
from (select id, userid, sum(score) as score
      , datestamp
from scores
group by userid, day(datestamp)) as x
where y.score >= x.score
and y.userid = x.userid
) =1 -- Top 3rd, 2nd, 1st    
order by y.score desc
;

基于总和的结果:

ID  USERID  SCORE   DATESTAMP
1   1       47.5    December, 06 2012 00:00:00+0000
8   2       16      December, 07 2012 00:00:00+0000
20  3       6       December, 08 2012 00:00:00+0000

更新了新的源数据样本

Simon,请看一下我自己的样本。随着您的数据不断变化,我使用了我的。 这是引用。我使用了纯 ansi 风格,没有任何 over partitiondense_rank。 另请注意,我使用的数据是前 2 名而不是前 3 名。您可以相应地进行更改。

猜猜看,答案比你的第一个数据给人的第一印象简单 10 倍......

SQLFIDDLE

查询到 1: -- 用户每天前 2 的总和

SELECT userid, sum(Score), datestamp
FROM scores t1
where 2 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and day(t1.datestamp) = day(t2.datestamp)
 order by t2.score desc)
group by userid, datestamp 
;

查询 1 的结果:

USERID  SUM(SCORE)  DATESTAMP
1       70      December, 06 2012 00:00:00+0000
1       30      December, 07 2012 00:00:00+0000
2       22      December, 06 2012 00:00:00+0000
2       25      December, 07 2012 00:00:00+0000
3       30      December, 06 2012 00:00:00+0000
3       30      December, 07 2012 00:00:00+0000

最终查询: -- 用户所有两天前 2 总和

SELECT userid, sum(Score)
FROM scores t1
where 2 >=
(SELECT count(*) 
 from scores t2
 where t1.score <= t2.score
 and t1.userid = t2.userid
 and day(t1.datestamp) = day(t2.datestamp)
 order by t2.score desc)
group by userid
;

最终结果:

USERID  SUM(SCORE)
1      100
2      47
3      60

这是我使用的数据直接计算的快照。

enter image description here

关于mysql - 为每个用户选择每天最高的 3 个分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13763855/

相关文章:

sql - 此 SQL 选择代码是否遵循良好实践?

mysql - 使用旧的 generator-angular-fullstack 版本

mysql - 将mysql中的列分成多列

java - 构建数据库查询的设计模式

php - PDO和缓存,如何在数据库类中实现?

mysql - 修复错误 1241 操作数应包含 1 列

php - 获取地理坐标附近的地点

php - Paypal IPN 与 MySQL 集成

mysql - 如何使用 MySQL 获取子查询中的结果值并将其用于比较?

mysql - 在 Django 1.7.8 中添加空白=True CharField 时迁移 SQL 无效