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)
- SQL Server:
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
相关产品推荐
相关产品推荐

