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

MySQL按currency_id分组获取对应最新timestamp记录的技术问询

解决MySQL按分组取最新记录的问题

哈哈,这种分组拿最新记录的需求真的是MySQL里的经典坑!我刚捡起来用的时候也踩过,太懂这种明明觉得简单却卡壳的感觉了😅

先给你说清楚为啥原来的写法不行:

  • 你第一个GROUP BY currency_id的查询,在MySQL默认配置(关闭ONLY_FULL_GROUP_BY)下,会返回每个分组里的任意一行,并不是你以为的“首行”,这是MySQL的非标准行为——换做PostgreSQL这类数据库直接会报错,因为你SELECT的列既不在GROUP BY里,也没用聚合函数。ORDER BY timestamp DESC只是对分组后的结果整体排序,根本管不到分组内部的行顺序,所以肯定拿不到最新的那条。
  • 那个LIMIT 6的写法完全是碰运气,不仅新增币种要改数字,还没法保证每个币种都能拿到最新记录,绝对不能用在正经业务里。

下面给你两种靠谱的解法,分版本适用:

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

这是最简洁直观的写法,MySQL 8.0及以上版本支持窗口函数,直接按分组内部排序取第一条:

SELECT id, price, currency_id, timestamp
FROM (
    SELECT 
        id, price, currency_id, timestamp,
        -- 按currency_id分组,每组内按timestamp倒序编号
        ROW_NUMBER() OVER (PARTITION BY currency_id ORDER BY timestamp DESC) AS row_num
    FROM prices
) temp
-- 取每组的第一条(也就是timestamp最新的那条)
WHERE row_num = 1;

如果同一个currency_id有多个记录的timestamp完全相同,ROW_NUMBER()会给它们编不同的号,只取一条;要是想把这些相同时间的都返回,可以换成RANK()或者DENSE_RANK()。

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

如果你的MySQL版本比较旧,不支持窗口函数,就用子查询先找出每个currency_id的最大timestamp,再和原表关联:

SELECT p.id, p.price, p.currency_id, p.timestamp
FROM prices p
INNER JOIN (
    -- 先拿到每个币种的最新时间戳
    SELECT currency_id, MAX(timestamp) AS latest_ts
    FROM prices
    GROUP BY currency_id
) latest ON p.currency_id = latest.currency_id AND p.timestamp = latest.latest_ts;

这里要注意:如果同一个币种有多个记录的timestamp等于最大时间,这个查询会返回所有这些记录。如果业务上要求只返回一条(比如取id最大的),可以把关联条件改成p.id = (SELECT MAX(id) FROM prices WHERE currency_id = latest.currency_id AND timestamp = latest.latest_ts),或者在子查询里同时取MAX(id)来关联,具体看你的业务逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:34:40