如何获取按size分组的最新记录并提取首个非零价格
解决获取各size最新非零价格的SQL问题
我来帮你搞定这个SQL查询的问题!先理清楚你的核心需求:
- 筛选出
size <= 32的所有记录 - 按
size分组,拿到每个尺码对应的**最新(日期最晚)**价格 - 从这些最新价格里,排除价格为0的,提取第一个非零的价格值(按
size降序的顺序)
先看原SQL的问题
你原来的写法是先排序再GROUP BY size,这种方式在MySQL里是不可靠的——GROUP BY的逻辑是做聚合计算,它并不会保证返回子查询排序后的第一行,实际运行时可能会从每个size组里随机取一条记录,所以得不到你想要的每个size的最新记录。
正确的解决方案(推荐用窗口函数,MySQL 8.0+支持)
用ROW_NUMBER()窗口函数可以精准地给每个size组内的记录按日期降序编号,编号为1的就是该尺码的最新记录,之后再过滤掉价格为0的,按size降序取第一个结果即可。
完整SQL语句:
SELECT price FROM ( SELECT *, -- 按size分组,每组内按date降序编号 ROW_NUMBER() OVER (PARTITION BY size ORDER BY date DESC) AS rn FROM prices WHERE size <= 32 -- 如果你的实际表有model_id和partner_id,在这里加上对应的过滤条件 -- AND model_id = '269' AND partner_id = '0' AND date <= '2021-10-19' ) t -- 取每个size的最新记录,并且排除价格为0的 WHERE rn = 1 AND price != 0 -- 按size降序排序,取第一个非零价格 ORDER BY size DESC LIMIT 1;
分步验证
先执行子查询里的窗口函数部分,会给每个size的记录编号:
id size price date rn 1 30 900 2021-10-02 1 3 30 800 2021-09-21 2 0 30 800 2021-10-01 3 5 32 0 2021-10-03 1 2 32 700 2021-09-11 2 4 32 800 2021-09-01 3 过滤
rn = 1的记录,得到每个size的最新数据:id size price date 5 32 0 2021-10-03 1 30 900 2021-10-02 最后排除
price = 0的记录,按size降序取第一条,就得到了目标值900。
兼容低版本MySQL(无窗口函数)
如果你的MySQL版本低于8.0,不支持窗口函数,可以用关联子查询先获取每个size的最新日期,再匹配对应的记录:
SELECT price FROM ( SELECT p.id, p.size, p.price, p.date FROM prices p INNER JOIN ( -- 先拿到每个size的最新日期 SELECT size, MAX(date) AS max_date FROM prices WHERE size <= 32 GROUP BY size ) p_max ON p.size = p_max.size AND p.date = p_max.max_date ) t WHERE price != 0 ORDER BY size DESC LIMIT 1;
内容的提问来源于stack exchange,提问作者Александр
相关产品推荐
相关产品推荐

