SQL实现用户各次存款间的小时间隔计算
需求:计算用户连续存款的小时间隔
需要编写SQL查询生成表,展示每个用户每连续两次存款之间的小时差值(例如第1次与第2次、第2次与第3次存款的时间间隔)。
原始数据查询语句
WITH q1 AS ( SELECT [UserId], [DepositAttemptDate], [AmountSystem] FROM [dbo].[v_DepositAttempts_Marketing] WHERE [DepositAttemptDate] >= '2024-01-01' AND [Status] IN ('Completed', 'Complete', 'Confirmed') AND [DepositType] = '' ORDER BY [UserId] ASC, [DepositAttemptDate] DESC )
原始数据示例
| User | Deposit Date | Value |
|---|---|---|
| 83815-fa85-466b-aaa7-00029c5 | 2024-10-30 12:42:58.793 | 8.698677800974 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-02-28 20:38:59.883 | 253.390000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-02-28 19:09:26.323 | 253.390000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-02-28 18:15:13.223 | 253.390000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-02-28 17:54:17.340 | 253.390000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-02-06 19:43:12.757 | 115.140000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-01-30 13:36:56.937 | 253.390000000000 |
| 62ac8-5d7f-464a-993c-00039b1 | 2024-01-09 14:20:03.440 | 405.040000000000 |
| 17f62-01c7-4a9c-ba28-0003b7f | 2024-05-15 18:50:18.350 | 51.500000000000 |
| 17f62-01c7-4a9c-ba28-0003b7f | 2024-03-21 22:59:57.217 | 51.500000000000 |
| 17f62-01c7-4a9c-ba28-0003b7f | 2024-01-21 13:24:44.393 | 51.500000000000 |
| 17f62-01c7-4a9c-ba28-0003b7f | 2024-01-03 20:13:14.167 | 51.500000000000 |
| 76763-384a-46cb-9a08-0004393 | 2024-09-06 18:51:29.677 | 103.000000000000 |
| 76763-384a-46cb-9a08-0004393 | 2024-09-05 00:01:44.587 | 51.500000000000 |
| 76763-384a-46cb-9a08-0004393 | 2024-08-25 03:42:08.290 | 103.000000000000 |
解决方案SQL
用窗口函数LAG()可以轻松实现这个需求——它能按用户分组,获取当前存款记录的上一次存款时间,再计算时间差转换为小时:
WITH q1 AS ( SELECT [UserId], [DepositAttemptDate], [AmountSystem], -- 按用户分组、存款日期升序,获取上一次存款时间 LAG([DepositAttemptDate]) OVER (PARTITION BY [UserId] ORDER BY [DepositAttemptDate] ASC) AS PreviousDepositDate FROM [dbo].[v_DepositAttempts_Marketing] WHERE [DepositAttemptDate] >= '2024-01-01' AND [Status] IN ('Completed', 'Complete', 'Confirmed') AND [DepositType] = '' ) SELECT [UserId] AS User, [DepositAttemptDate] AS CurrentDepositDate, PreviousDepositDate, -- 计算小时差并保留两位小数 ROUND(DATEDIFF(SECOND, PreviousDepositDate, [DepositAttemptDate]) / 3600.0, 2) AS HoursBetweenDeposits, [AmountSystem] AS CurrentDepositValue FROM q1 -- 过滤掉无前置存款的记录(用户第一次存款) WHERE PreviousDepositDate IS NOT NULL ORDER BY [UserId] ASC, [DepositAttemptDate] ASC;
如果需要和原始查询一样按最新存款在前排序,改用LEAD()函数获取下一次存款时间即可:
WITH q1 AS ( SELECT [UserId], [DepositAttemptDate], [AmountSystem], -- 按用户分组、存款日期降序,获取下一次存款时间 LEAD([DepositAttemptDate]) OVER (PARTITION BY [UserId] ORDER BY [DepositAttemptDate] DESC) AS NextDepositDate FROM [dbo].[v_DepositAttempts_Marketing] WHERE [DepositAttemptDate] >= '2024-01-01' AND [Status] IN ('Completed', 'Complete', 'Confirmed') AND [DepositType] = '' ) SELECT [UserId] AS User, [DepositAttemptDate] AS CurrentDepositDate, NextDepositDate, ROUND(DATEDIFF(SECOND, NextDepositDate, [DepositAttemptDate]) / 3600.0, 2) AS HoursBetweenDeposits, [AmountSystem] AS CurrentDepositValue FROM q1 WHERE NextDepositDate IS NOT NULL ORDER BY [UserId] ASC, [DepositAttemptDate] DESC;
内容的提问来源于stack exchange,提问作者lpca
相关产品推荐
相关产品推荐

