如何对此查询进行分组以返回单个结果?

时间:2015-02-04 16:24:47

标签: mysql

我有一个我无法改变的数据库结构,但我想找到最有效的方法来获取这些数据。

我们有一个游戏对象有3个级别,在每个级别结束时,游戏会将一个分数保存到数据库中,其中级别得分在适当的列中,0s列在其他级别的列中。这里有说明:

数据库结构:

UserID | Score1| Score2| Score3| CreatedAt
1      |0      |0      |3      |<today>
1      |2      |0      |0      |<today>
1      |0      |5      |0      |<today>
1      |0      |0      |2      |<yesterday>
1      |0      |6      |0      |<yesterday>
1      |1      |0      |0      |<yesterday>
1      |0      |0      |6      |<3 days ago>
1      |0      |7      |0      |<3 days ago>
1      |4      |0      |0      |<3 days ago>

现在,是的,拥有类似UserID的结构是更好的解决方案得分| LevelNumber | CreatedAT,但由于其他一些情况,我们无法改变结构。

所以,我希望能够做的是,在给定日期的情况下,提出一个可获得三个最新分数的查询。例如,在上面的示例中,查询今天的日期将返回Score1:2,Score2:5,Score3:3的结果;并且在2天前查询将得分1:4,得分2:7,得分3:6;

3 个答案:

答案 0 :(得分:1)

这可以解决您的问题:

select userid
     , s1
     , s2
     , s3
  from (
            select userid
                 , createdat
                 , sum(score1) s1
                 , sum(score2) s2
                 , sum(score3) s3
              from table
          group by userid
                 , createdat
       ) t
 where t.createdat = (
                        select max(t1.createdat)
                          from table t1
                         where t1.userid = t.userid
                           and t1.createdat <= <date_queried>
                      )
     ;

答案 1 :(得分:0)

如果我理解你的情况,这个查询应该没问题:

select max(Score1), max(Score2),max(Score3) FROM table where CreatedAt=<today>

答案 2 :(得分:0)

这是一种方式......

DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table
(id INT NOT NULL AUTO_INCREMENT PRIMARY KEY
,UserID INT NOT NULL
,Score1 INT NOT NULL
,Score2 INT NOT NULL
,Score3 INT NOT NULL
,CreatedAt DATE NOT NULL
);

INSERT INTO my_table (userid,score1,score2,score3,createdat) VALUES
(1,0,0,3,'2015-02-04'),
(1,2,0,0,'2015-02-04'),
(1,0,5,0,'2015-02-04'),
(1,0,0,2,'2015-02-03'),
(1,0,6,0,'2015-02-03'),
(1,1,0,0,'2015-02-03'),
(1,0,0,6,'2015-02-01'),
(1,0,7,0,'2015-02-01'),
(1,4,0,0,'2015-02-01');

SELECT id,userid,score1 score,1 levelno,createdat FROM my_table
UNION ALL
SELECT id,userid,score2,2,createdat FROM my_table
UNION ALL
SELECT id,userid,score3,3,createdat FROM my_table
;
+----+--------+-------+---------+------------+
| id | userid | score | levelno | createdat  |
+----+--------+-------+---------+------------+
|  1 |      1 |     0 |       1 | 2015-02-04 |
|  2 |      1 |     2 |       1 | 2015-02-04 |
|  3 |      1 |     0 |       1 | 2015-02-04 |
|  4 |      1 |     0 |       1 | 2015-02-03 |
|  5 |      1 |     0 |       1 | 2015-02-03 |
|  6 |      1 |     1 |       1 | 2015-02-03 |
|  7 |      1 |     0 |       1 | 2015-02-01 |
|  8 |      1 |     0 |       1 | 2015-02-01 |
|  9 |      1 |     4 |       1 | 2015-02-01 |
|  1 |      1 |     0 |       2 | 2015-02-04 |
|  2 |      1 |     0 |       2 | 2015-02-04 |
|  3 |      1 |     5 |       2 | 2015-02-04 |
|  4 |      1 |     0 |       2 | 2015-02-03 |
|  5 |      1 |     6 |       2 | 2015-02-03 |
|  6 |      1 |     0 |       2 | 2015-02-03 |
|  7 |      1 |     0 |       2 | 2015-02-01 |
|  8 |      1 |     7 |       2 | 2015-02-01 |
|  9 |      1 |     0 |       2 | 2015-02-01 |
|  1 |      1 |     3 |       3 | 2015-02-04 |
|  2 |      1 |     0 |       3 | 2015-02-04 |
|  3 |      1 |     0 |       3 | 2015-02-04 |
|  4 |      1 |     2 |       3 | 2015-02-03 |
|  5 |      1 |     0 |       3 | 2015-02-03 |
|  6 |      1 |     0 |       3 | 2015-02-03 |
|  7 |      1 |     6 |       3 | 2015-02-01 |
|  8 |      1 |     0 |       3 | 2015-02-01 |
|  9 |      1 |     0 |       3 | 2015-02-01 |
+----+--------+-------+---------+------------+

SELECT a.*
  FROM 
     ( SELECT id,userid,score1 score,1 levelno,createdat FROM my_table
       UNION ALL
       SELECT id,userid,score2,2,createdat FROM my_table
       UNION ALL
       SELECT id,userid,score3,3,createdat FROM my_table
     ) a
 WHERE score > 0
   AND createdat <= '2015-02-02'
 ORDER 
    BY createdat DESC
     , levelno
 LIMIT 3;

+----+--------+-------+---------+------------+
| id | userid | score | levelno | createdat  |
+----+--------+-------+---------+------------+
|  9 |      1 |     4 |       1 | 2015-02-01 |
|  8 |      1 |     7 |       2 | 2015-02-01 |
|  7 |      1 |     6 |       3 | 2015-02-01 |
+----+--------+-------+---------+------------+