You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用SQL计算连续行数值差值?以燃油价格为例

计算数据表中连续行数值差值的SQL方案

嘿,我来帮你搞定这个连续行差值计算的需求!针对你给出的包含日期、Speed、Petrol和Diesel的表格,这里有几种不同的SQL实现方案,你可以根据自己使用的数据库来选择:

通用方案(支持窗口函数的数据库:MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)

这是最简洁高效的方法,利用LAG()窗口函数直接获取前一行的对应数值,然后计算差值:

SELECT
    Date,
    Speed,
    Petrol,
    Diesel,
    -- 计算Speed与前一行的差值
    Speed - LAG(Speed) OVER (ORDER BY Date) AS Speed_Diff,
    -- 计算Petrol与前一行的差值
    Petrol - LAG(Petrol) OVER (ORDER BY Date) AS Petrol_Diff,
    -- 计算Diesel与前一行的差值
    Diesel - LAG(Diesel) OVER (ORDER BY Date) AS Diesel_Diff
FROM
    your_table_name; -- 记得把这里替换成你的实际表名

说明:LAG(column) OVER (ORDER BY Date)会按照日期排序,取出当前行的上一行对应列的值。因为第一行没有前一行数据,所以它的差值会显示为NULL,这是正常的结果。另外注意你的数据里2018-04-03是缺失的,这个方案会直接跳过该日期,只计算现有数据中连续行的差值。

老版本MySQL兼容方案(无窗口函数)

如果你用的是MySQL 8.0以下的版本,不支持窗口函数,可以用自连接+子查询的方式实现:

SELECT
    t1.Date,
    t1.Speed,
    t1.Petrol,
    t1.Diesel,
    t1.Speed - t2.Speed AS Speed_Diff,
    t1.Petrol - t2.Petrol AS Petrol_Diff,
    t1.Diesel - t2.Diesel AS Diesel_Diff
FROM
    your_table_name t1
LEFT JOIN
    your_table_name t2 ON t2.Date = (SELECT MAX(Date) FROM your_table_name WHERE Date < t1.Date)
ORDER BY
    t1.Date;

说明:子查询会找到当前日期之前的最大日期(也就是前一行的日期),然后通过自连接把前后两行的数据关联起来,进而计算差值。同样第一行的差值会是NULL。

补全日历日期后的差值计算(以PostgreSQL为例)

如果你的需求是按日历日计算差值,即使某天没有数据也要显示(比如补上2018-04-03的记录再计算),可以先生成连续的日期序列,再和原数据表关联后计算:

-- 先生成覆盖数据日期范围的连续日期序列
WITH date_series AS (
    SELECT generate_series(
        (SELECT MIN(Date) FROM your_table_name),
        (SELECT MAX(Date) FROM your_table_name),
        INTERVAL '1 day'
    ) AS date
),
-- 关联原数据,用前一天的值补全缺失日期的数值(也可以保留为NULL,根据需求调整)
filled_data AS (
    SELECT
        ds.date::DATE,
        COALESCE(t.Speed, LAG(t.Speed) OVER (ORDER BY ds.date)) AS Speed,
        COALESCE(t.Petrol, LAG(t.Petrol) OVER (ORDER BY ds.date)) AS Petrol,
        COALESCE(t.Diesel, LAG(t.Diesel) OVER (ORDER BY ds.date)) AS Diesel
    FROM date_series ds
    LEFT JOIN your_table_name t ON ds.date::DATE = t.Date
)
-- 最后计算每日与前一日的差值
SELECT
    date,
    Speed,
    Petrol,
    Diesel,
    Speed - LAG(Speed) OVER (ORDER BY date) AS Speed_Diff,
    Petrol - LAG(Petrol) OVER (ORDER BY date) AS Petrol_Diff,
    Diesel - LAG(Diesel) OVER (ORDER BY date) AS Diesel_Diff
FROM filled_data;

说明:这里用递归CTE生成了连续的日期,然后用COALESCE和LAG补全了缺失日期的数值,之后再计算差值,这样就能得到完整日历日的差值结果。

内容的提问来源于stack exchange,提问作者Athira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 08:22:51