sql - 如何用相同的ID标记彼此在15秒内的交易?
问题描述
我有一个包含以下列的数据集,例如:
终端ID | 交易日期 | 交易时间 |
---|---|---|
1 | 2020-10-01 | 05:49:40 |
1 | 2020-10-01 | 05:49:46 |
1 | 2020-10-01 | 06:20:05 |
2 | 2020-10-01 | 03:31:15 |
2 | 2020-10-01 | 03:31:25 |
2 | 2020-10-01 | 03:31:35 |
我想创建一个列,它为在同一个 TerminalID 上进行的那些交易提供一个公共 ID,并且彼此在 15 秒内。示例表最终应该是这样的:
终端ID | 交易日期 | 交易时间 | 交叉ID |
---|---|---|---|
1 | 2020-10-01 | 05:49:40 | 1 |
1 | 2020-10-01 | 05:49:46 | 1 |
1 | 2020-10-01 | 06:20:05 | 2 |
2 | 2020-10-01 | 03:31:15 | 3 |
2 | 2020-10-01 | 03:31:25 | 3 |
2 | 2020-10-01 | 03:31:35 | 3 |
前两次交易是在 15 秒内在同一个终端上进行的(他们获得 crossID 1),而第三次终端交易发生的时间要晚得多(所以它获得 crossID 2,并且该终端上 15 秒内没有更多交易) . 最后三笔交易是在前一笔交易的 15 秒内完成的,因此即使在 2 号终端上的第一笔交易和最后一笔交易之间的间隔超过 15 秒,它们也会获得相同的 CrossID,因为它们之间有一个交易连接它们.
我已经使用 Pandas 和 Datetime 在 Python 中编写了一些工作代码,但是我的数据集太大而无法用 Python 加载,所以我需要使用 SQL(我只用于非常基本的查询)。任何帮助将非常感激。
解决方案
假设这 15 分钟不跨越午夜,则使用 lag 获取上一次时间,并在差值大于 15 分钟时总结一个标志:
select t.*,
sum(case when prev_transactionTime > dateadd(minute, -15, transactionTime) then 0 else 1 end) over
(partition by terminalId order by transactionDate, transactionTime) as crossID
from (select t.*,
lag(transactionTime) over (partition by terminalId, transactionDate order by transactionTime) as prev_transactionTime
from t
) t;
如果 15 分钟的时间可以超过午夜,那么您应该真正修复数据,因此在一列中包含日期/时间。您可以使用以下方法解决此问题:
select t.*,
sum(case when prev_transactionDateTime > dateadd(minute, -15, transactionDateTime) then 0 else 1 end) over
(partition by terminalId order by transactionDateTime) as crossID
from (select t.*,
lag(v.transactionDateTime) over (partition by t.terminalId order by v.transactionDateTime) as prev_transactionDateTime
from t cross apply
(values (convert(datetime, t.transactionDate) + convert(datetime, t.transactionTime))
) v(transactionDateTime)
) t;
SQL Server 允许datetime
将两个值相加,这可能是组合它们的最简单方法。
推荐阅读
- android - 在没有使用 nRF Connect 的解决方法的情况下,无法使用自定义应用程序连接到 BLE 设备
- python - Discord.py task.loop 用于更改 cog 不工作的状态
- javascript - 如何使此图像地图元素具有响应性?
- c++ - 将从命令行翻译的库链接到 Make
- html - 未应用 Google 字体。我正在尝试将 Google 字体应用于容器内的文本
- c# - 在 Blazor 组件中使用 for 循环获取 ArgumentOutOfRangeException
- reactjs - 本地服务器问题,启动反应应用程序
- solaris - 如何在 Solaris 中查找和替换字符串?
- xamarin.forms - Xamarin.Forms 使 WebView 可编辑
- python - Python 不读取 unicode U + FE0F