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

如何通过SQL查询获取每月各产品的最低价记录

获取每月各产品最低价记录的SQL解决方案

嘿,我来帮你搞定这个查询需求!先理清楚你的场景:

你有一张product_prices表,结构和数据是这样的:

IDProduct_idPricePrice_date
1152021-10-01
2162021-10-25
3252021-10-01
4262021-10-25
5132021-09-01
6152021-09-25
7272021-09-01
8232021-09-25

你需要找出每个月份里,每个产品对应的最低价记录,期望得到的结果是这样的:

IDProduct_idPricePrice_date
1152021-10-01
3252021-10-01
5132021-09-01
8232021-09-25

下面给你两种实用的解决方案,你可以根据自己用的数据库选择:

方案一:用窗口函数ROW_NUMBER()(推荐)

这个方法清晰又高效,适合支持窗口函数的数据库(比如MySQL 8.0+、PostgreSQL、SQL Server、Oracle等)。核心思路是给每个产品的每月记录按价格排序,取最低价的那条:

SELECT ID, Product_id, Price, Price_date
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (
            PARTITION BY DATE_FORMAT(Price_date, '%Y-%m'), Product_id
            ORDER BY Price ASC, Price_date ASC
        ) AS rn
    FROM product_prices
) AS ranked
WHERE rn = 1;

给你拆解下这段代码:

  • DATE_FORMAT(Price_date, '%Y-%m'):把日期转成年-月格式,这样就能按月份分组啦。如果是SQL Server可以换成FORMAT(Price_date, 'yyyy-MM'),Oracle用TO_CHAR(Price_date, 'YYYY-MM'),根据你的数据库调整就行。
  • PARTITION BY:按「年份月份+产品ID」分组,这样每个产品每个月的记录会被分到一个组里。
  • ORDER BY Price ASC, Price_date ASC:先按价格升序排,确保最低价排在最前面;如果同一个月同一个产品有多个相同最低价,就按日期升序取最早的那条(要是想取最晚的,把Price_date ASC改成DESC就行)。
  • WHERE rn = 1:筛选出每个组里排名第一的记录,也就是我们要的最低价记录。

方案二:子查询分组(兼容老版本数据库)

如果你用的是不支持窗口函数的老版本数据库(比如MySQL 5.x),可以用这个方法:先通过子查询算出每个月份每个产品的最低价,再关联原表拿到完整记录:

SELECT p.ID, p.Product_id, p.Price, p.Price_date
FROM product_prices p
JOIN (
    SELECT 
        DATE_FORMAT(Price_date, '%Y-%m') AS month,
        Product_id,
        MIN(Price) AS min_price
    FROM product_prices
    GROUP BY month, Product_id
) AS m
ON DATE_FORMAT(p.Price_date, '%Y-%m') = m.month
AND p.Product_id = m.Product_id
AND p.Price = m.min_price;

注意:

这个方法如果遇到同一月份同一产品有多个相同最低价的记录,会返回所有符合条件的记录;而窗口函数的方法可以通过排序规则控制只返回一条。你可以根据自己的实际需求选择。

内容的提问来源于stack exchange,提问作者Sergey Vershinin Yazzi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 15:59:05