You need to enable JavaScript to run this app. PostgreSQL按天分组获取最大val值及对应name的查询实现
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL按天分组获取最大val值及对应name的查询实现

问题根因
  • PostgreSQL 严格遵循SQL标准的聚合校验规则:当使用GROUP BY完成分组聚合时,SELECT子句中出现的列,要么是纳入GROUP BY的分组列,要么是被聚合函数(如max()、sum())包裹的列,否则会直接抛出语法错误。
  • 如果强行将name字段加入GROUP BY的分组条件,分组粒度会从“按单日聚合”变为“按单日+单name聚合”,最终返回的是每个天、每个name各自的val最大值,完全偏离统计单日全局最大值的需求。
  • 普通分组聚合的逻辑只能返回分组的统计值本身,无法自动带出该统计值对应的关联行字段,因此需要换用其他查询逻辑实现需求。
可落地的实现方案

方案1:窗口函数实现(PostgreSQL原生支持,执行效率高)

核心思路:按天对数据做分区,在每个单日的分区内将val按从高到低排序,直接取每个分区排序首位的整行数据,即可同时获取day、val、name三个字段。

SELECT day, name, val
FROM (
    SELECT 
        day, 
        name, 
        val,
        -- 按天分区,val降序排序
        ROW_NUMBER() OVER (PARTITION BY day ORDER BY val DESC) AS sort_rank
    FROM 你的实际表名 -- 替换为真实表名即可
) ranked_data
WHERE sort_rank = 1;

边界场景说明:如果同一天存在多个并列的最大值(比如示例中12-01-2021的Een和Twee的val均为1,都是当日最大值),ROW_NUMBER()会强制为并列值分配不同序号,仅返回其中一行。如果需要保留所有并列最大值的记录,将ROW_NUMBER()替换为RANK()即可。

方案2:聚合结果关联原表实现

核心思路:先通过原有的分组逻辑计算出每日的val最大值,再将聚合结果和原表做内连接,匹配同日期、val等于当日最大值的行,拿到对应的name字段。

SELECT t.day, t.name, t.val
FROM 你的实际表名 t
INNER JOIN (
    -- 先算出每日的max val
    SELECT day, max(val) AS daily_max_val
    FROM 你的实际表名
    GROUP BY day
) max_table
ON t.day = max_table.day 
AND t.val = max_table.daily_max_val;

特点说明:这种写法会保留所有和当日最大值匹配的行,不会出现并列值被随机截断的问题,更适合需要完整保留并列统计结果的场景。

以你提供的示例数据为例,最终查询会返回两行结果:11-01-2021对应val=19、name=Drie;12-01-2021对应val=1,匹配到name为Een和Twee的记录,完全匹配需求。

注意:如果当前表的day字段是MM-DD-YYYY格式的字符串,建议先将其转换为DATE类型再做分区、排序和关联,避免字符串排序逻辑导致的数值匹配偏差。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.09 16:06:04