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

MySQL中如何根据validFrom日期筛选今日有效价格的行

解决方案:获取每个类型的最新有效价格记录

这是个很常见的分组取最新有效数据的需求,我给你提供几种简洁高效的MySQL实现方式,你可以根据你的MySQL版本选择合适的方案:

先准备测试数据(方便你验证)

CREATE TABLE IF NOT EXISTS price_history (
    type INT,
    validfrom DATE,
    price INT
);

INSERT INTO price_history VALUES
(1, '2018-01-15', 10),
(1, '2018-01-20', 20),
(1, '2018-01-25', 30),
(2, '2018-01-01', 12),
(3, '2018-01-01', 18);

方法1:使用窗口函数(MySQL 8.0+ 推荐)

这是最直观简洁的写法,利用ROW_NUMBER()窗口函数给每个类型的有效记录按日期倒序编号,取编号为1的就是最新记录:

SELECT type, validfrom, price
FROM (
    SELECT 
        type, 
        validfrom, 
        price,
        -- 按type分组,每个组内按validfrom倒序排序,生成序号
        ROW_NUMBER() OVER (PARTITION BY type ORDER BY validfrom DESC) AS rn
    FROM price_history
    -- 筛选出不晚于当前日期的记录
    WHERE validfrom <= '2018-01-21'
) t
-- 取每个组的第一条(最新的)记录
WHERE rn = 1;

方法2:关联子查询(兼容MySQL 5.x)

如果你的MySQL版本还不支持窗口函数,可以用这种写法,逻辑是:找出每条符合日期条件的记录,且同类型下没有比它更晚的有效记录,那它就是该类型的最新记录:

SELECT ph.type, ph.validfrom, ph.price
FROM price_history ph
WHERE ph.validfrom <= '2018-01-21'
AND NOT EXISTS (
    SELECT 1 
    FROM price_history ph2
    WHERE ph2.type = ph.type
    AND ph2.validfrom <= '2018-01-21'
    -- 存在同类型且日期更晚的有效记录,则当前记录不是最新的
    AND ph2.validfrom > ph.validfrom
);

方法3:MAX()分组关联(兼容所有版本)

先分组找出每个类型的最大有效日期(不晚于当前日期),再关联原表获取对应的价格:

SELECT ph.type, ph.validfrom, ph.price
FROM price_history ph
JOIN (
    -- 先获取每个type的最新有效日期
    SELECT type, MAX(validfrom) AS max_validfrom
    FROM price_history
    WHERE validfrom <= '2018-01-21'
    GROUP BY type
) ph_max ON ph.type = ph_max.type AND ph.validfrom = ph_max.max_validfrom;

补充说明

  • 如果你的表数据量较大,建议给type和validfrom创建联合索引:CREATE INDEX idx_type_validfrom ON price_history(type, validfrom);,这能大幅提升查询效率。
  • 窗口函数的写法最易读和维护,优先推荐在MySQL8.0及以上版本使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:36:36