[英]How to calculate difference between mysql-rows, kind of different
我有一张桌子可以接收游戏的结果。 每个游戏都有其自己的ID,仅持续7天。 每天一次,所有游戏将其结果放入此表中(技能A,技能B ...的结果分别存储在列中)。
我需要能够在MySQL中检索的内容:我需要显示每个游戏(game_id)及其所有结果,以及每一天的结果之间的进度(可能上升或下降)。
这样的结果应该是:
Game_id date result_a progress result_b progress
1234 2013-09-01 10 0 8 0
1234 2013-09-02 08 -2 6 -2
1234 2013-09-03 15 7 10 4
1234 2013-09-04 19 4 13 3
4321 2013-09-01 09 0 7 0
4321 2013-09-02 18 9 9 2
4321 2013-09-03 15 -3 11 2
4321 2013-09-04 09 -6 16 4
有什么技巧可以轻松解决这个问题(它可能会变成大约4000行的东西……)?
如果您可以在将该值提交给数据库之前使用PHP工作,则可以拥有整周的所有值,并且可以遍历每个数据,然后根据当前值与上一个值之间的差异来更新进度,然后用新的进度值更新表。
请原谅我只编写伪代码,因为我不太擅长PHP
//Get the values from the Database, only the columns, game_id, date, result_a, result_b
for(i=0;all values)
{
progress[i] = result[i]- result[i-1];
}
//finally save the result as you have prgress value for all i's
以下查询应产生所需的输出(列顺序除外)。 这里的技巧是检查以前的游戏ID是否仍然相同(变量),如果是,则用先前的结果数据(变量)相减以获得结果,否则只需返回0。
为什么列顺序有些不同? 这是因为否则变量将被当前值覆盖,因此结果始终为0。 这就是为什么您必须在比较和减法之后设置“上一个”变量。
SELECT
@progress_a := IF(@prevGameId = data.game_id,
data.result_a - @prevResultA,
0) AS 'progress_a',
@prevResultA := data.result_a AS 'result_a',
@progress_b := IF(@prevGameId = data.game_id,
data.result_b - @prevResultB,
0) AS 'progress_b',
@prevResultB := data.result_b AS 'result_b',
data.registration_date,
(@prevGameId := data.game_id) AS 'game_id'
FROM (SELECT
game_id,
result_a,
result_b,
registration_date
FROM games
ORDER BY game_id, registration_date
) AS data
JOIN (SELECT
@prevGameId := NULL,
@prevResultA := NULL,
@prevResultB := NULL
) dummy
最后一个JOIN是初始化变量所必需的(如果您只能触发1个查询)。 否则,您可以使用SET语句初始化变量(在SELECT之前)。
FROM中的SELECT是必需的,因为不能保证每个游戏的记录都可以分组。 因此,我确保将它们一起订购并在注册日期进行排序。 优点是,如果您不能保证每个注册日期(每个游戏)都是唯一的,则可以对每个游戏/ registration_date进行分组。
注意:如果遇到严重的性能问题(我认为应该不是),则实际上必须在应用程序中对其进行处理或在插入数据时计算进度(冗余存储“进度”数据)。
试试这个-它在您的sqlfiddle中起作用
SELECT g.id, g.game_id, g.registration_date as today, y.registration_date as yesterday
,g.result_a as result_a
,COALESCE(g.result_a - y.result_a,0) as progress_a
,g.result_b as result_b
,COALESCE(g.result_b - y.result_b,0) as progress_b
FROM games g
LEFT JOIN games y
ON g.game_id = y.game_id
AND g.registration_date > y.registration_date
WHERE NOT EXISTS
(SELECT *
FROM games
WHERE games.registration_date > y.registration_date
AND games.registration_date < g.registration_date)
ORDER BY g.game_id, g.registration_date, y.registration_date
如果日期始终是连续的(即,以前的游戏始终是昨天),则SQL查询变得更加简单:
SELECT g.id, g.game_id, g.registration_date as today, y.registration_date as yesterday
,g.result_a as result_a
,COALESCE(g.result_a - y.result_a,0) as progress_a
,g.result_b as result_b
,COALESCE(g.result_b - y.result_b,0) as progress_b
FROM games g
LEFT JOIN games y
ON g.game_id = y.game_id
AND DATEDIFF(g.registration_date, y.registration_date) = 1
ORDER BY g.game_id, g.registration_date, y.registration_date
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.