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

PostgreSQL 9.6:按组优先选取foo=A行的实现方法

解决PostgreSQL按组优先选取指定行的问题

先明确你的原始数据(假设表名为your_table):

group | foo | value
------+-----+------
1     | A   | a
1     | B   | b
1     | C   | c
2     | B   | b2
2     | A   | a2
3     | B   | b3
3     | C   | c3

需求很清晰:每组返回一行,优先选取组内foo = 'A'的行,如果没有就任选一行。下面是两种高效的实现方式:

方法1:使用窗口函数ROW_NUMBER()

这是通用的SQL方案,其他支持窗口函数的数据库也能复用:

SELECT "group", foo, value
FROM (
    SELECT 
        "group", 
        foo, 
        value,
        -- 给每组的行分配优先级:A排1,其他排2
        ROW_NUMBER() OVER (
            PARTITION BY "group" 
            ORDER BY CASE WHEN foo = 'A' THEN 1 ELSE 2 END
        ) AS row_num
    FROM your_table
) ranked_rows
WHERE row_num = 1;

原理说明:

  • PARTITION BY "group":把数据按group字段拆分成独立的组
  • ORDER BY CASE ...:给foo='A'的行设置最高优先级,确保它在组内排第一
  • 外层筛选row_num=1,就能拿到每组的目标行

方法2:使用PostgreSQL特有的DISTINCT ON

这个语法更简洁,是PostgreSQL的专属特性,写起来更清爽:

SELECT DISTINCT ON ("group") "group", foo, value
FROM your_table
-- 先按组排序,再按优先级排序,确保A行在组内最前面
ORDER BY "group", CASE WHEN foo = 'A' THEN 1 ELSE 2 END;

原理说明:

  • DISTINCT ON ("group")会返回每组的第一行
  • ORDER BY子句先按group分组排序,再按优先级排序,这样foo='A'的行就会成为每组的第一行被选中;如果组内没有A,就取排序后的第一行(也就是原数据里的第一个匹配行)

最终输出结果

两种方法都会得到你想要的结果:

group | foo | value
------+-----+------
1     | A   | a
2     | A   | a2
3     | B   | b3

⚠️ 注意:group是PostgreSQL的关键字,所以在SQL里要用双引号"group"括起来,避免语法错误。如果你的实际字段名不是这个,记得替换成自己的字段名。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 10:00:54