SQL按ID分区查找与购买日期最近的前置报价正时间差方案咨询
高效实现方案
完全不需要用WHILE循环,不管是数据库处理还是本地数据处理,用分组排序逻辑就能实现,性能比循环高至少两个数量级。
核心逻辑
按ID分区后,只保留所有早于对应购买日期的报价,取其中时间最大的那条就是距离购买日最近的有效报价,直接计算时间差即可。
1 SQL实现(适配绝大多数关系型数据库/数仓,适合大数据量场景)
假设你有两张表:
- 报价记录表
quote_records:存储所有ID的历史报价,字段包括id(产品ID)、quote_time(报价时间)、其他报价相关字段 - 购买记录表
purchase_records:存储所有ID的购买信息,字段包括id(产品ID)、purchase_time(购买时间)
示例代码:
WITH filter_quote AS ( SELECT q.id, q.quote_time, p.purchase_time, -- 同ID下报价时间倒序排列,最接近购买时间的排第一 ROW_NUMBER() OVER (PARTITION BY q.id ORDER BY q.quote_time DESC) AS rn FROM quote_records q JOIN purchase_records p ON q.id = p.id WHERE q.quote_time < p.purchase_time -- 只保留早于购买时间的报价 ) SELECT id, quote_time 有效报价时间, purchase_time 购买时间, -- 按分钟计算时间差,可按需调整时间单位 TIMESTAMPDIFF(MINUTE, quote_time, purchase_time) 时间差_分钟 FROM filter_quote WHERE rn = 1;
如果有多个报价时间完全相同的场景,把ROW_NUMBER换成RANK()即可保留所有同时间的有效报价,只需要取一条的话保留ROW_NUMBER就行。可以给id和quote_time加联合索引,进一步提升查询效率。
2 Python Pandas实现(适合本地处理小批量数据集)
如果你是用Python处理本地的结构化数据,用Pandas的分组逻辑即可实现:
import pandas as pd # 假设df_quote为报价DataFrame,df_purchase为购买DataFrame # 先关联两张表,过滤出早于购买时间的报价 df_merge = pd.merge(df_quote, df_purchase, on="id") df_merge = df_merge[df_merge["quote_time"] < df_merge["purchase_time"]] # 按ID分组,取每个ID下报价时间最大的记录 df_result = df_merge.loc[df_merge.groupby("id")["quote_time"].idxmax()] # 计算时间差(单位:分钟) df_result["时间差_分钟"] = (df_result["purchase_time"] - df_result["quote_time"]).dt.total_seconds() / 60
内容的提问来源于stack exchange,提问作者Loic Trobas
相关产品推荐
相关产品推荐

