PostgreSQL 9.6中按"item_id"分组取每组最后"value_num"值的方法
实现方法:按item_id分组取每个组内最新date的value_num
针对你的PostgreSQL 9.6需求,这里有两种实用的实现方式,适配不同场景:
方法一:使用PostgreSQL专属的DISTINCT ON(简洁高效)
这是PostgreSQL特有的语法,代码简洁且性能优异,尤其适合有合适索引的场景:
SELECT DISTINCT ON (item_id) item_id, value_num AS last_value_num FROM events ORDER BY item_id, date DESC;
原理说明:
DISTINCT ON (item_id)确保每个item_id只返回一行结果ORDER BY item_id, date DESC先按item_id分组,再在每个组内按date降序排列,这样每个组的第一行就是date最新的记录,对应的value_num就是你要的"最后一个值"
如果存在同一个item_id下多条记录date相同的情况,你可以再加一个唯一排序字段(比如主键id)来保证结果确定性:
SELECT DISTINCT ON (item_id) item_id, value_num AS last_value_num FROM events ORDER BY item_id, date DESC, id DESC;
方法二:使用标准SQL窗口函数ROW_NUMBER()(兼容性好)
如果需要兼容其他数据库,或者更灵活的分组逻辑,窗口函数是通用方案:
WITH ranked_events AS ( SELECT item_id, value_num, -- 按item_id分组,组内按date降序编号,最新的记录编号为1 ROW_NUMBER() OVER (PARTITION BY item_id ORDER BY date DESC) AS rn FROM events ) SELECT item_id, value_num AS last_value_num FROM ranked_events WHERE rn = 1;
原理说明:
PARTITION BY item_id将数据按item_id划分成不同的分组ORDER BY date DESC让每个分组内date最新的记录排在最前面ROW_NUMBER()为每个分组内的记录生成顺序编号,取rn = 1的行就是每个分组的目标记录
同样,若有date重复的情况,可添加额外排序字段(如id DESC)到ORDER BY中确保结果稳定。
内容的提问来源于stack exchange,提问作者prafi
相关产品推荐
相关产品推荐

