Mysql - 模拟先前多行(不仅仅是一行)的滞后

标签 mysql sql window-functions

经过几个小时的努力,模拟延迟(我使用的是 MySQL 5.6,没有升级选项),并发现了两个功能问题,我来这里寻求一点帮助,我现在完全迷失了。

经过长时间的处理后,我在存储过程中获得了一个临时表,其中包含按用户 ID 和购买日期排列的以下数据顺序(示例):

样本获取方式:

SELECT 
purchaseId
,userId
,purchaseDate 
FROM tempPurchases
WHERE userId > 69
ORDER BY userId, purchaseDate;


+------------+--------+--------------+
| purchaseId | userId | purchaseDate |
+------------+--------+--------------+
|       2074 |     70 | 2018-11-12   |
|       2072 |     70 | 2018-11-30   |
|       2108 |     71 | 2018-01-23   |
|       2114 |     71 | 2018-02-27   |
|       2130 |     71 | 2018-03-07   |
|       2115 |     71 | 2018-04-17   |
|       2105 |     71 | 2018-11-12   |
|       2112 |     71 | 2018-11-30   |
|       2145 |     72 | 2018-01-21   |
|       2141 |     72 | 2018-01-23   |
|       2136 |     72 | 2018-02-01   |
|       2148 |     72 | 2018-03-02   |
|       2158 |     72 | 2018-06-06   |
|       2137 |     72 | 2018-07-04   |
|       2139 |     72 | 2018-07-11   |
|       2153 |     72 | 2018-10-18   |
|       2135 |     72 | 2018-10-25   |
|       2157 |     72 | 2018-11-12   |
|       2147 |     72 | 2018-12-30   |
|       2184 |     73 | 2018-02-21   |
|       2166 |     73 | 2018-03-14   |
|       2176 |     73 | 2018-05-12   |
|       2186 |     73 | 2018-07-09   |
|       2173 |     73 | 2018-08-25   |
|       2162 |     73 | 2018-11-12   |
|       2165 |     73 | 2018-11-30   |
+------------+--------+--------------+

该规范是通过 30 天内的购买获得“奖励”(我使用 TIMESTAMPDIFF(DAYS) 和 lag 来计算一个日期与前一个日期之间的天数差异。这里的问题是奖金还会与之前的多行进行比较,而不仅仅是上面的行。(A 列的逻辑)

例如,在下一个示例中,对于用户 ID 72,购买 ID 2136 与 2141 匹配,但也与 2145 匹配,当然这是可变的,就像一个人今天购买了 10 次,昨天购买了 20 次。

所以想要的结果是:

+------------+--------+--------------+-----------+------------+--------------------------+
| purchaseId | userId | purchaseDate | days diff | A (streak) | B (streak without reset) |
+------------+--------+--------------+-----------+------------+--------------------------+
|       2074 |     70 | 2018-11-12   |         0 |          0 |                        0 |
|       2072 |     70 | 2018-11-30   |        18 |          1 |                        1 |
|       2108 |     71 | 2018-01-23   |         0 |          0 |                        0 |
|       2114 |     71 | 2018-02-27   |        35 |          0 |                        0 |
|       2130 |     71 | 2018-03-07   |         8 |          1 |                        1 |
|       2115 |     71 | 2018-04-17   |        41 |          0 |                        0 |
|       2105 |     71 | 2018-11-12   |       209 |          0 |                        0 |
|       2112 |     71 | 2018-11-30   |        18 |          1 |                        1 |
|       2145 |     72 | 2018-01-21   |         0 |          0 |                        0 |
|       2141 |     72 | 2018-01-23   |         2 |          1 |                        1 |
|       2136 |     72 | 2018-02-01   |         9 |          2 |                        2 |
|       2148 |     72 | 2018-03-02   |        29 |          1 |                        3 |
|       2158 |     72 | 2018-06-06   |        96 |          0 |                        0 |
|       2137 |     72 | 2018-07-04   |        28 |          1 |                        1 |
|       2139 |     72 | 2018-07-11   |         7 |          1 |                        2 |
|       2153 |     72 | 2018-10-18   |        99 |          0 |                        0 |
|       2135 |     72 | 2018-10-25   |         7 |          1 |                        1 |
|       2157 |     72 | 2018-11-12   |        18 |          2 |                        2 |
|       2147 |     72 | 2018-12-30   |        48 |          0 |                        0 |
|       2184 |     73 | 2018-02-21   |         0 |          0 |                        0 |
|       2166 |     73 | 2018-03-14   |        21 |          1 |                        1 |
|       2176 |     73 | 2018-05-12   |        59 |          0 |                        0 |
|       2186 |     73 | 2018-07-09   |        58 |          0 |                        0 |
|       2173 |     73 | 2018-08-25   |        47 |          0 |                        0 |
|       2162 |     73 | 2018-11-12   |        79 |          0 |                        0 |
|       2165 |     73 | 2018-11-30   |        18 |          1 |                        1 |
+------------+--------+--------------+-----------+------------+--------------------------+

完全迷失了多重连接/左连接和滞后模拟,任何提示、评论或答案都将得到重视。请不要在评论中怀疑或提出任何问题。

问题: 如何计算 A streak 并考虑上面几行的“滞后”? 我的实际方法是使用光标,但目前两者都不起作用。

更新:

预期结果是获得“奖励条纹”,处理同一用户 ID 的上述行。例如:

userId 72 于 1 月 1 日进行购买(购买 1)(第一行值为 0)。然后在 1 月 10 日再次(购买 2),因此少于 30 天:1 分(10 天)。同样是在 2001 年 15 月(购买 3),因此购买 2(5 天)之间的差异为 1 分,购买 1(15 天)的差异为 1 分。总奖金:3 (0 + 1 + (1+1))

最佳答案

我相信就这么简单,select里面的子查询统计过去30天内的购买次数:

SELECT t.*, (
    SELECT COUNT(*)
    FROM t AS x
    WHERE userId = t.userId 
    AND purchaseDate <  t.purchaseDate
    AND purchaseDate >= t.purchaseDate - INTERVAL 30 DAY
) AS purchases_within_30days
FROM t

关于Mysql - 模拟先前多行(不仅仅是一行)的滞后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54512208/

相关文章:

SQL 更改表以添加列,它会执行任何操作 "scary"吗?

mysql - 仅当主查询具有子查询返回的所有行时才返回

sql - 当我期望多行时,Postgres 中的交叉表函数返回一行输出

MySQL 根据匹配日期将多行合并为一行

sql - 如何在 PostgreSQL 中使用 LAST_VALUE?

mysql - SQL查询: join

mysql - COUNT(DISTINCT(CASE WHEN 寻找函数而不是列?MySQL

sql - 通过链接服务器在远程服务器上创建数据库

mysql - 如何在 phpmyadmin 中启用关系 View

PHP-Laravel : How to save without time overlapping in DB