如何获取分组的最后一条记录?SQL查询问题求助
问题原因
你原来的查询错误在于把value加入了GROUP BY子句,这会让数据库把id、name、value三者都相同的记录归为一组,而不是按你需要的id+name分组。同一个id+name下如果有不同的value,就会生成多条分组结果,这就是重复记录出现的原因。
解决方案
方法1:使用窗口函数(推荐,通用SQL语法)
用ROW_NUMBER()窗口函数给每个id+name组内的记录按时间倒序编号,然后取编号为1的那条(也就是最新的记录):
SELECT time, id, name, value FROM ( SELECT time, id, name, value, ROW_NUMBER() OVER (PARTITION BY id, name ORDER BY time DESC) AS rn FROM table WHERE time >= (now() - '00:05:00') ) t WHERE rn = 1;
PARTITION BY id, name:按id和name分组ORDER BY time DESC:组内按时间从新到旧排序rn = 1:取每个组的第一条(最新)记录
方法2:子查询关联(适用于不支持窗口函数的数据库)
先查询每个id+name组的最大时间,再关联原表获取对应的value:
SELECT t.time, t.id, t.name, t.value FROM table t JOIN ( SELECT id, name, MAX(time) AS max_time FROM table WHERE time >= (now() - '00:05:00') GROUP BY id, name ) tm ON t.id = tm.id AND t.name = tm.name AND t.time = tm.max_time WHERE t.time >= (now() - '00:05:00');
方法3:PostgreSQL专属语法DISTINCT ON
如果你用的是PostgreSQL,可以用更简洁的DISTINCT ON:
SELECT DISTINCT ON (id, name) time, id, name, value FROM table WHERE time >= (now() - '00:05:00') ORDER BY id, name, time DESC;
DISTINCT ON (id, name):确保每个id+name只返回一条记录ORDER BY id, name, time DESC:指定先按分组字段排序,再按时间倒序,这样每组的第一条就是最新记录
验证结果
以你提供的原始数据为例,上述方法会返回每个id+name组内时间最大的那条记录,比如A-D11会取2022-08-31 11:59:00+02,3,"A","D11",完全符合“获取最后一条记录”的需求。
内容的提问来源于stack exchange,提问作者user16511234
相关产品推荐
相关产品推荐

