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

PostgreSQL中按单字段分组并保留分组内最小值对应ID的正确SQL查询方法

嘿,我来帮你搞定这个PostgreSQL的分组查询问题~

首先得说清楚你原来的语句为啥跑不通:你之前写的SELECT id, MIN(value), category FROM table GROUP BY category会报错,核心原因是PostgreSQL的GROUP BY规则很严格——SELECT里的列要么得在GROUP BY里,要么得用聚合函数(比如MIN、MAX这种)处理。你的id列既没在GROUP BY里,也没有聚合操作,数据库根本不知道该选分组里的哪个id对应最小的value,所以肯定无法正常运行。

接下来给你几种靠谱的解决方案:

方法1:用窗口函数(通用型,适用于大部分数据库)

窗口函数是处理这种“分组取特定行”需求的常用方式,用ROW_NUMBER()给每个分组里的行按value排序,然后取排序第一的那行就行:

SELECT id, value, category
FROM (
    SELECT 
        id, 
        value, 
        category,
        -- 按category分组,每组内按value升序排,最小的value排第1
        ROW_NUMBER() OVER (PARTITION BY category ORDER BY value ASC) AS row_num
    FROM your_table_name -- 记得把这里换成你的实际表名
) ranked_data
WHERE row_num = 1;

如果同一个category里有多个行的value都是最小值,这个方法只会返回其中一行;要是想把所有最小value的行都返回,把ROW_NUMBER()换成RANK()就行。

方法2:PostgreSQL专属的简洁写法——DISTINCT ON

PostgreSQL有个独有的语法DISTINCT ON,能直接帮你保留每个分组的第一行,写起来特别短:

SELECT DISTINCT ON (category) id, value, category
FROM your_table_name
-- 先按category分组,再按value升序,这样每组的第一行就是最小value的那行
ORDER BY category, value ASC;

这个方法性能也很好,而且代码简洁,如果你只需要每个分组里的一条最小value记录,强烈推荐用这个。

方法3:子查询关联(传统写法)

先通过子查询找出每个category的最小value,再关联原表找到对应的id和其他列:

SELECT t.id, t.value, t.category
FROM your_table_name t
INNER JOIN (
    -- 先拿到每个category的最小value
    SELECT category, MIN(value) AS min_value
    FROM your_table_name
    GROUP BY category
) min_values 
ON t.category = min_values.category AND t.value = min_values.min_value;

这个方法的特点是,如果同一个category里有多个行的value都是最小值,会把这些行都返回,适合需要保留所有最小value记录的场景。

你可以根据自己的实际需求选合适的方法就行啦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 02:47:37