我在 MySQL 语法中使用 MariaDB 10.2.4,并尝试根据每个客户每笔交易的行时间戳(不是日历日)来计算过去 24 小时内发生的交易数量。
这是一个手动制作的表格,显示我想要的输出是什么。输入将全部是相同的列,不包括输出 (trans_count) 和 row_number 列。
第 3 行。我感兴趣的时间范围是 2022-02-11 22:53:50(order_date 列中的值)到 2022-02-10 22:53:50(order_date - 间隔 1 天)按客户 ID 1111171。第 4 行和第 6 行与此匹配,因此第 3 行的输出为 3(包括第 3 行)。
第 4 行。客户 1111171 的时间范围为 2022-02-11 06:49:36 至 2022-02-10 06:49:36。 第 6,8,9,10 行属于该时间范围内并且是相同的 customer_id,因此 trans_count 值为 5。
行号 | 订单号 | 客户 ID | 订单_日期 | 美元价值 | trans_count |
---|---|---|---|---|---|
1 | 8888883 | 1111100 | 2022-02-14 01:10:04 | 2256.0 | 1 |
2 | 8888837 | 1111100 | 2022-02-12 05:46:32 | 1457.2 | 1 |
3 | 8888812 | 1111171 | 2022-02-11 22:53:50 | 1757.2 | 3 |
4 | 8888887 | 1111171 | 2022-02-11 06:49:36 | 1350.2 | 5 |
5 | 8888804 | 1111100 | 2022-02-11 03:10:07 | 1853.6 | 1 |
6 | 8888866 | 1111171 | 2022-02-11 01:20:26 | 1053.0 | 4 |
7 | 8888833 | 1111181 | 2022-02-10 21:09:05 | 253.2 | 1 |
8 | 8888874 | 1111171 | 2022-02-10 18:06:55 | 1958.6 | 3 |
9 | 8888829 | 1111171 | 2022-02-10 10:11:59 | 1456.2 | 2 |
10 | 8888802 | 1111171 | 2022-02-10 09:55:31 | 956.6 | 1 |
11 | 8888835 | 1111100 | 2022-02-09 19:40:24 | 756.4 | 2 |
12 | 8888810 | 1111123 | 2022-02-09 01:34:56 | 3179.5 | 1 |
13 | 8888850 | 1111100 | 2022-02-08 20:00:20 | 629.0 | 1 |
14 | 8888821 | 1111171 | 2022-02-08 17:59:05 | 1249.45 | 2 |
15 | 8888809 | 1111171 | 2022-02-08 06:25:15 | 1250.0 | 1 |
16 | 8888837 | 1111147 | 2022-02-08 06:18:15 | 184.6 | 1 |
17 | 8888836 | 1111171 | 2022-02-07 12:01:47 | 88.28 | 1 |
18 | 8888808 | 1111147 | 2022-02-05 12:02:49 | 3008.7 | 3 |
19 | 8888890 | 1111147 | 2022-02-05 11:48:16 | 1543.31 | 2 |
20 | 8888805 | 1111147 | 2022-02-05 11:37:55 | 2617.4 | 1 |
我还打算应用一些其他过滤器,例如仅计算 1000 以上的 Dollar_value,但我希望这不会影响计数的逻辑。
我已经能够在 PySpark 中做到这一点,但我无法重复相同的逻辑。这是我将其合并到的函数的片段。
'''
# Function to calculate number of seconds from number of days
days = lambda i: i * 86400
# Create window by casting timestamp to long (number of seconds) then defining the number of days you wish to review
w = (Window.partitionBy('customer_id').orderBy(F.col(date_column).cast('long')).rangeBetween(-days(monitor_length_days), 0))
# Add total value of transactions undertaken within time frame by customer_id
filteredDF = filteredDF.withColumn(output_name, F.count('customer_id').over(w))
'''
如有任何疑问请告诉我,
不幸的是,MariaDB 不允许您在一段时间内创建一个窗口,因此您需要采用不同的方法。解决此问题的一种方法是将表
JOIN
设为自身,其中 customer_id
值相同且 order_date
位于之前 24 小时内。然后,您可以计算连接表中的行数以获得 trans_count
值:
SELECT o.customer_id, o.order_date,
COUNT(c.customer_id) AS trans_count
FROM orders o
JOIN (SELECT customer_id, order_date
FROM orders
) c ON c.customer_id = o.customer_id AND c.order_date BETWEEN o.order_date - INTERVAL 1 DAY AND o.order_date
GROUP BY o.customer_id, o.order_date
ORDER BY o.order_date DESC
输出(用于您的示例数据):
customer_id order_date trans_count
1111100 2022-02-14 01:10:04 1
1111100 2022-02-12 05:46:32 1
1111171 2022-02-11 22:53:50 3
1111171 2022-02-11 06:49:36 5
1111100 2022-02-11 03:10:07 1
1111171 2022-02-11 01:20:26 4
1111181 2022-02-10 21:09:05 1
1111171 2022-02-10 18:06:55 3
1111171 2022-02-10 10:11:59 2
1111171 2022-02-10 09:55:31 1
1111100 2022-02-09 19:40:24 2
1111123 2022-02-09 01:34:56 1
1111100 2022-02-08 20:00:20 1
1111171 2022-02-08 17:59:05 2
1111171 2022-02-08 06:25:15 2
1111147 2022-02-08 06:18:15 1
1111171 2022-02-07 12:01:47 1
1111147 2022-02-05 12:02:49 3
1111147 2022-02-05 11:48:16 2
1111147 2022-02-05 11:37:55 1
请注意,对于第 15 行,
trans_count
应为 2
,因为第 17 行在 24 小时内有先前的交易。
可以按如下方式完成:
SELECT
row_number,
order_no,
customer_id,
order_date,
dollar_value,
(
SELECT COUNT(*)
FROM your_table t2
WHERE t2.customer_id = t1.customer_id
AND t2.order_date BETWEEN (t1.order_date - INTERVAL 1 DAY) AND t1.order_date
) AS trans_count
FROM your_table t1;