【问题标题】:MySQL table - calculate points for last 12 monthsMySQL 表 - 计算过去 12 个月的积分
【发布时间】:2017-01-23 17:11:38
【问题描述】:

我有一个用户社区,用户可以在其中获得特定操作的“用户积分”,例如写评论(+5 分)、上传图片(+10 分)等。这些积分可用于“购买”诸如一件 T 恤(-100 分)。每个操作都记录到 MySQL 表 userpoints_log

  • id (int, PK)
  • user_id (int, FK to user table)
  • action_id (int, FK to action table)
  • points(int,点本身,例如 +5 或 -100)
  • created_at(日期)

目前,我计算每个用户的用户点数,只需将此表中所有点日志的SUM()(由 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 年 4 月 1 日排除 +1000 点,那么其中 500 点已经被使用(2016 年 5 月 1 日为 -500)。

我可以使用哪个公式或查询来获得正确的值?

【问题讨论】:

  • 您是否尝试查看GROUP BYclose?我想你想念GROUP BY user_id 之类的东西或任何你想要的群组
  • 您能否详细说明为什么您在该示例中所需的输出是 500,而不是 0?
  • @IkeWalker:更新了问题。总结:500分是正确的结果,因为当用户使用他的积分(-500)时,他首先使用他的“最旧”积分,而他不能使用未来的积分。如果我们假设,我们从 2016 年 4 月 1 日排除 +1000 点,那么其中 500 点已被使用(2016 年 5 月 1 日为 -500)。
  • @ShikatsuKagaminara:你说得对,我错过了“分组依据”,但仅在我的示例中,而不是在我的真实代码中

标签: mysql


【解决方案1】:
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)

这是伪代码,但您可以使用该逻辑。
1.查找第一个+点日期
2. 变化——第一次赚取前的积分数据

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-16
    • 1970-01-01
    • 1970-01-01
    • 2012-03-23
    • 2020-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多