2017-01-23 39 views
0

我有一个用户社区,用户可以通过写评论(+5分),上传图片(+10分)等特定动作获得“用户积分”。积分习惯于“买”像T恤衫(-100分)的东西。每一个动作都记录到MySQL表userpoints_logMySQL表格 - 计算过去12个月的积分

  • ID(INT,PK)
  • USER_ID(INT,FK到用户表)
  • 的action_id(INT,FK行动表)
  • 点(INT,点本身就像+5或-100)
  • created_at(日期)

目前,我计算userpoints为每个用户,只需通过进行在这个表中的所有点登录(由USER_ID标识)的:

SELECT SUM(points) AS 'result' FROM userpoints_log 
WHERE user_id = X 
GROUP BY user_id 

现在我需要改变这个计算,因为所有的(积极)点应只适用于12个月。首先,我只是做以下几点:

SELECT SUM(points) AS 'result' FROM userpoints_log 
WHERE user_id = X AND created_at > DATE(NOW()-INTERVAL 1 YEAR) 
GROUP BY user_id 

但是,这给了我一些错误的结果。例如,对于下面的数据集:

created_at |points 
------------------ 
2016-04-01 | +1000 
2016-05-01 | -500 
2016-06-01 | +500 

如果我将在2017年4月15日运行上面的查询,我会得到的结果是0点(-500 + 500),这是不正确的,因为用户应该有500分。

500分是正确的结果,因为当用户使用他的积分(-500)时,他首先使用他的“最老的”积分,他不能使用未来的积分。如果我们假设,我们排除2016-04-01的+1000分,那么已经使用了500分(2016-05-01为-500分)。

任何想法哪些公式或查询我可以使用,以获得正确的值?

+0

您是否试图查看'GROUP BY'close? 我想你错过了'GROUP BY user_id'或任何你想要的组合 –

+1

你能否提供一些细节,说明为什么你想要的输出在那个例子中是500,而不是0? –

+0

@IkeWalker:更新了问题。总结:500分是正确的结果,因为当用户使用他的分数(-500)时,他首先使用他的“最老”分数,并且他不能使用未来的分数。如果我们假设,我们排除2016-04-01的+1000分,那么已经使用了500分(2016-05-01为-500分)。 – bernhardh

回答

0
SELECT SUM(case when points < 0 and create_at < (
    select min(create_at) from userpoints_log where user_id = X 
    and created_at > DATE(NOW()-INTERVAL 1 YEAR) and points > 0 
) then 0 else points) AS 'result' 
FROM userpoints_log 
WHERE user_id = X AND created_at > DATE(NOW()-INTERVAL 1 YEAR) 

这是psedo代码,但您可以使用该逻辑。
1.找到第一个+点日期
2.变化点数据第一次获得之前