SQL如何基于单列聚合,取每个var_id_id分组的第一条数据?
SQL实现按单列分组取每组排序后第一条的方案
原查询错误原因
你原来的查询把唯一字段VR.id放到了GROUP BY分组条件里,等于每一行都是独立分组,自然不会得到按var_id_id聚合去重的效果。
方案1:PostgreSQL专属语法 DISTINCT ON(最简洁)
PostgreSQL支持DISTINCT ON (分组列)语法,可以直接保留每个分组的第一行,只需要配合排序规则即可:
SELECT DISTINCT ON (VR.var_id_id) VR.id, VR.var_val, VR.id_res_id, VR.var_id_id, AR.device_id, VR.var_val_conv FROM public.api_site_varsresults as VR JOIN public.modbus_modbusvariable as MV ON VR.var_id_id = MV.id JOIN public.api_site_results as AR ON VR.id_res_id = AR.id WHERE AR.device_id = 'abc123' -- 先按分组列排序,再按id倒序,保证每个分组里id最大的排在第一位 ORDER BY VR.var_id_id, VR.id DESC;
该写法直接就能得到目标结果,不需要额外嵌套逻辑。
方案2:窗口函数(全数据库通用)
如果你用的是MySQL、SQL Server等不支持DISTINCT ON的数据库,可以用ROW_NUMBER()窗口函数实现:
WITH ranked_data AS ( SELECT VR.id, VR.var_val, VR.id_res_id, VR.var_id_id, AR.device_id, VR.var_val_conv, -- 按var_id_id分组,组内按id倒序排名,id最大的行排名为1 ROW_NUMBER() OVER (PARTITION BY VR.var_id_id ORDER BY VR.id DESC) AS rn FROM public.api_site_varsresults as VR JOIN public.modbus_modbusvariable as MV ON VR.var_id_id = MV.id JOIN public.api_site_results as AR ON VR.id_res_id = AR.id WHERE AR.device_id = 'abc123' ) -- 只取每个分组排名第一的行 SELECT id, var_val, id_res_id, var_id_id, device_id, var_val_conv FROM ranked_data WHERE rn = 1;
内容的提问来源于stack exchange,提问作者Manuel Santi
相关产品推荐
相关产品推荐

