如何在SQL中从每日记录表格生成价格日期区间
解决思路:给连续相同价格的日期段打分组标签
核心逻辑是识别连续相同价格的日期区间,给每个独立区间分配唯一标识,再按标识分组聚合起止日期。
方法1:SQL实现(适用于数据库端处理)
用窗口函数LAG()对比当前行与前一行的价格,当价格变化时生成新的分组ID,最后按分组ID和价格聚合:
WITH price_groups AS ( SELECT Price, Date, -- 当当前价格与前一天不同时,分组ID加1 SUM(CASE WHEN Price = LAG(Price) OVER (ORDER BY Date) THEN 0 ELSE 1 END) OVER (ORDER BY Date) AS group_id FROM your_price_table ) SELECT Price, MIN(Date) AS Start_Date, MAX(Date) AS End_Date FROM price_groups GROUP BY Price, group_id ORDER BY Start_Date;
解释:
LAG(Price) OVER (ORDER BY Date)获取前一天的价格- 用
SUM(...) OVER (...)累加分组标识:每次价格变化时,分组ID递增,确保连续相同价格的行属于同一组 - 最后按
Price和group_id分组,取每组的最小/最大日期作为起止日期
方法2:Python实现(适用于本地数据处理,比如Pandas)
用Pandas的diff()判断价格变化,生成分组标签,再聚合:
import pandas as pd # 假设数据已加载为df,Date字段是datetime类型 df['Date'] = pd.to_datetime(df['Date']) df = df.sort_values('Date') # 生成分组ID:价格变化时分组ID加1 df['group_id'] = (df['Price'] != df['Price'].shift(1)).cumsum() # 分组聚合 result = df.groupby(['Price', 'group_id']).agg( Start_Date=('Date', 'min'), End_Date=('Date', 'max') ).reset_index(drop=['group_id']).sort_values('Start_Date') print(result)
解释:
df['Price'].shift(1)获取前一行价格,!=判断是否变化cumsum()累加布尔值(True=1,False=0),生成连续相同价格的分组ID- 按
Price和group_id分组,取起止日期
关键注意点
- 必须先按
Date排序,否则连续日期的判断会出错 - 分组时必须同时用
Price和group_id,避免把不同区间的相同价格合并 - 如果存在缺失日期(比如周末无记录),需要先补全日期再处理,否则会误判非连续日期为连续区间(比如周五和下周一价格相同,但中间缺周六周日,是否算连续区间需根据业务规则调整)
内容的提问来源于stack exchange,提问作者IUE
相关产品推荐
相关产品推荐

