Mysql - 模拟前面多行(不只是一行)的滞后
Mysql - Simulate lag with multiple previous rows (not just one)
经过几个小时的努力,模拟延迟(我在 MySQL 5.6 上没有升级选项),并发现了两个功能问题,我来这里寻求一点帮助,我是现在完全迷失在这里。
经过长时间的处理,我在存储过程中得到了一个临时 table,其中包含按用户 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 天内购买 "bonus"(我使用 TIMESTAMPDIFF(DAYS)
和滞后来计算一个日期和前一个日期之间的天数差异。这里的问题是奖金也与前面的多行进行比较,而不仅仅是上面的行。(A 列的逻辑)
例如,在下一个示例中,对于 userid 72,purchaseId 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 |
+------------+--------+--------------+-----------+------------+--------------------------+
完全迷失了多次 join/left 加入和滞后模拟,任何提示、评论或答案都将被预测。有疑问请评论或提问。
问题:
如何计算 A 连胜并注意上面几行的 "lag"?
我的实际方法是使用游标,但目前两者都不起作用。
更新:
预期的结果是 "bonus streak" 为相同的用户 ID 处理上述行。例如:
userId 72 在 01/jan 购买(购买 1)(第一行值为 0)。然后在 10/1 再次(购买 2),因此少于 30 天:1 点(10 天)。同样在 15 月 1 日(购买 3),因此购买 2(5 天)和购买 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 5.6 上没有升级选项),并发现了两个功能问题,我来这里寻求一点帮助,我是现在完全迷失在这里。
经过长时间的处理,我在存储过程中得到了一个临时 table,其中包含按用户 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 天内购买 "bonus"(我使用 TIMESTAMPDIFF(DAYS)
和滞后来计算一个日期和前一个日期之间的天数差异。这里的问题是奖金也与前面的多行进行比较,而不仅仅是上面的行。(A 列的逻辑)
例如,在下一个示例中,对于 userid 72,purchaseId 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 |
+------------+--------+--------------+-----------+------------+--------------------------+
完全迷失了多次 join/left 加入和滞后模拟,任何提示、评论或答案都将被预测。有疑问请评论或提问。
问题: 如何计算 A 连胜并注意上面几行的 "lag"? 我的实际方法是使用游标,但目前两者都不起作用。
更新:
预期的结果是 "bonus streak" 为相同的用户 ID 处理上述行。例如:
userId 72 在 01/jan 购买(购买 1)(第一行值为 0)。然后在 10/1 再次(购买 2),因此少于 30 天:1 点(10 天)。同样在 15 月 1 日(购买 3),因此购买 2(5 天)和购买 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