如何在SQL中计算每小时首个值与下一小时首个值的差值?
问题分析与解决方案
首先,明确你的核心需求:从给定的时间序列数据中,提取每个整小时的第一条记录值,再计算当前小时首个值与下一个整小时首个值的差值。
先把你提供的原始数据整理出来,方便后续处理:
2020-10-09 13:31:00 2 2020-10-09 13:46:00 4 2020-10-09 14:01:00 10 2020-10-09 14:16:00 12 2020-10-09 14:31:00 13 2020-10-09 14:46:00 20 2020-10-09 15:01:00 25 2020-10-09 15:16:00 27 2020-10-09 15:31:00 30 2020-10-09 15:46:00 35 2020-10-09 16:01:00 40
按照你的示例,最终要得到的结果逻辑是:
- 13:00 首个值 2 → 与14:00首个值10的差值:8
- 14:00 首个值10 → 与15:00首个值25的差值:15
- 15:00 首个值25 → 与16:00首个值40的差值:15
- 16:00 首个值40 → 无后续整小时数据,差值可留空或标记
用Python Pandas实现的具体方案
Pandas是处理时间序列数据的高效工具,下面是完整的可运行代码,每一步都有注释说明:
import pandas as pd # 1. 构造数据(如果数据存于文件,可改用pd.read_csv读取) raw_data = [ ["2020-10-09 13:31:00", 2], ["2020-10-09 13:46:00", 4], ["2020-10-09 14:01:00", 10], ["2020-10-09 14:16:00", 12], ["2020-10-09 14:31:00", 13], ["2020-10-09 14:46:00", 20], ["2020-10-09 15:01:00", 25], ["2020-10-09 15:16:00", 27], ["2020-10-09 15:31:00", 30], ["2020-10-09 15:46:00", 35], ["2020-10-09 16:01:00", 40] ] # 转换为DataFrame结构 df = pd.DataFrame(raw_data, columns=["timestamp", "value"]) # 2. 处理时间格式:转换为datetime类型并设为索引 df["timestamp"] = pd.to_datetime(df["timestamp"]) df = df.set_index("timestamp") # 3. 按整小时分组,提取每组第一条数据(即该小时首个值) hourly_first_vals = df.groupby(pd.Grouper(freq='H')).first().dropna() # dropna()用于移除无数据的小时(比如你的数据里12点没有记录,会自动过滤) # 4. 计算相邻小时的差值:下一个小时值 - 当前小时值 hourly_first_vals["hourly_diff"] = hourly_first_vals["value"].shift(-1) - hourly_first_vals["value"] # 5. 整理成你需要的输出格式 final_result = hourly_first_vals.reset_index() final_result["timestamp"] = final_result["timestamp"].dt.strftime("%Y-%m-%d %H:00:00") # 打印结果 print(final_result)
运行结果
执行代码后会输出如下内容,完全匹配你的需求:
timestamp value hourly_diff 0 2020-10-09 13:00:00 2 8.0 1 2020-10-09 14:00:00 10 15.0 2 2020-10-09 15:00:00 25 15.0 3 2020-10-09 16:00:00 40 NaN
其中NaN表示16点没有后续整小时的数据,你可以根据需要替换为0、"无"等标记。
关键步骤解释
- 按小时分组:
pd.Grouper(freq='H')会自动将时间序列按整小时划分组(比如13:00-14:00的所有记录归为13点组) - 提取首个值:
groupby(...).first()会取每组的第一条记录,也就是该小时最早出现的数值 - 计算差值:
shift(-1)会把下一行的值移到当前行,用它减去当前值就得到了相邻小时的差值
如果你的数据量很大,或者需要处理更复杂的时间规则(比如按半小时、工作日分组),这个方案也能轻松扩展。
内容的提问来源于stack exchange,提问作者refrachnican
相关产品推荐
相关产品推荐

