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

SQL中如何计算选定日期与上月同期的价格差值

计算选定日期与上月同期的价格差值

嘿,这个需求很常见,我来给你两种靠谱的SQL实现方案,适配不同的查询场景!

方案一:自连接(适合单一指定日期的查询)

如果用户只需要查询某一个特定日期(比如2024-02-01)和上月同期的价格差,用自连接的方式最直接,逻辑也清晰。

思路是把表和自己做关联:一边取选定日期的产品价格,另一边取对应产品上月同期的价格,然后计算差值。

SELECT
    current_data.`Product Name`,
    current_data.Date AS current_date,
    current_data.Price AS current_price,
    previous_month_data.Price AS previous_month_price,
    -- 用COALESCE处理上月无数据的情况,避免出现NULL结果
    COALESCE(current_data.Price - previous_month_data.Price, NULL) AS price_difference
FROM
    your_table_name current_data
LEFT JOIN
    your_table_name previous_month_data
ON
    current_data.`Product Name` = previous_month_data.`Product Name`
    -- 自动计算上月同期日期,支持跨年(比如2024-01-01会匹配2023-12-01)
    AND previous_month_data.Date = DATE_SUB(current_data.Date, INTERVAL 1 MONTH)
WHERE
    current_data.Date = '2024-02-01'; -- 替换成用户选定的日期

关键细节说明:

  • DATE_SUB(current_data.Date, INTERVAL 1 MONTH):MySQL里的日期计算函数,自动处理不同月份天数和跨年的情况,直接得到上月同一天的日期。如果是其他数据库,对应函数略有不同:
    • SQL Server:DATEADD(month, -1, current_data.Date)
    • Oracle:ADD_MONTHS(current_data.Date, -1)
  • LEFT JOIN:确保即使某个产品在上月同期没有数据,当前日期的记录依然会被保留,差值显示为NULL(如果需要显示0,把COALESCE里的NULL改成0即可)。

方案二:窗口函数(适合批量计算所有日期的差值)

如果需要一次性计算所有日期与上月同期的价格差,用窗口函数LAG()会更高效,不用多次关联表。

SELECT
    `Product Name`,
    Date AS current_date,
    Price AS current_price,
    -- 按产品分组、日期排序,取上月同期的价格
    LAG(Price, DAYOFMONTH(Date)) OVER (PARTITION BY `Product Name` ORDER BY Date) AS previous_month_price,
    COALESCE(Price - LAG(Price, DAYOFMONTH(Date)) OVER (PARTITION BY `Product Name` ORDER BY Date), NULL) AS price_difference
FROM
    your_table_name;

注意点:

这个方法的前提是你的数据每日都有完整记录(没有缺失日期)。如果存在日期缺失,LAG()的偏移量可能会匹配到错误的日期,这时还是方案一的自连接更可靠。

通用注意事项

  • 记得把your_table_name替换成你的实际表名。
  • 如果是在应用中接收用户输入的日期,可以把固定日期换成参数(比如MySQL用?,PostgreSQL用$1),避免SQL注入风险。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:51:21