日期在 30 天后过期的累积问题

cumulative problem if date is expired after 30 days

我仍然找不到累积问题的解决方案。任何人都可以提供帮助或提出任何解决方案。非常感谢。

我有2个table:交易(日期,user_id,价格,服务组)和积分(服务组,积分)。用户获得的积分为价格*积分。

我留下了加入交易和积分 table 然后我计算了每个用户的积分并将其添加到新列中。

我使用 window 函数 sum(new_point) over(partition by user_id order by date) 来计算累积点,但我在 30 天后卡住了过期点。

要求:每天计算每个用户的累计积分。 (30 天后积分将从交易日起过期)

例如: 用户A的交易:

1/1/2020: 20, 80
2/1/2020: 10
3/1/2020: 9
1/2/2020: 10
2/2/2020: 20
3/2/2020: 30

=> 结果像这样

 1/1/2020: 20 + 80 = 100
2/1/2020: 100 + 10 = 110
3/1/2020: 110 + 9 = 119
1/2/2020:  119 + 10 = 129
2/2/2020:  29 + 20 = 49 (point of 1/1/2020 expired)
3/2/2020: 39 + 30 = 69 (point of 2/1/2020 expired)
  1. 测试于 dbfiddle
  2. 如果我误解了你的问题,请告诉我。
WITH new_sum AS (
SELECT 
  t.user_id, t.date, t.price, p.point,
  t.price+COALESCE(p.point,0) AS new_point, 
  SUM(t.price+COALESCE(p.point,0)) OVER(PARTITION BY user_id ORDER BY date) AS running_sum
FROM transactions t
LEFT JOIN point p ON t.service_group = p.service_group
),
expired AS (
SELECT 
  user_id,
  DATE_ADD(DATE_ADD(date, INTERVAL 1 MONTH),INTERVAL 1 DAY) AS date, 
  running_sum AS expired_points
FROM new_sum
)

SELECT 
  s.user_id, s.date, 
  s.running_sum - COALESCE(e.expired_points,0) AS final
FROM new_sum s
LEFT JOIN expired e
ON s.user_id = e.user_id
AND s.date = e.date;

您可以为此在 window 函数中使用范围,方法是将日期解释为数字:

select date, sum(point) over (order by datediff(date,'1970-01-01') asc range between 32 preceding and 0 following) point
from (
    select date, sum(price*point) point
    from transactions
    join point using (service_group)
    where user_id=1
    group by date
) user_points

请注意,在您的示例中,您使用的似乎是 32 天到期,而不是 30 天。

fiddle