我有一个我无法改变的数据库结构,但我想找到最有效的方法来获取这些数据。
我们有一个游戏对象有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;
答案 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 |
+----+--------+-------+---------+------------+