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

如何解决Presto中GROUP BY报错‘必须是聚合表达式或在GROUP BY子句’问题?

这个问题和另一Stack Overflow问题类似,但本文提供了更简单的示例(原问题的查询过于复杂难以理解)。

示例(模拟)数据

idgenderkg
4f5a07ca-02e0-8981-3c30-4d9924a169a3male103
4f5a07ca-02e0-8981-3c30-4d9924a169a3male85
4f5a07ca-02e0-8981-3c30-4d9924a169a3male469
e05d54e9-8292-b26c-5618-8a3712b4fc44female33

期望结果

idgenderkg
4f5a07ca-02e0-8981-3c30-4d9924a169a3male85
e05d54e9-8292-b26c-5618-8a3712b4fc44female33
e05d54e9-8292-b26c-5618-8a3712b4fc44female36
01f8bbfd-cfc6-3b97-8bc1-8da6f0b4a9a8female92

(目标是相同id仅显示一次,按kg排序后取第一个匹配项)

问题描述

使用以下查询语句时:

SELECT 
    p.id,
    p.gender,
    p.kg
FROM patient p
ORDER BY p.kg
GROUP BY 1

出现报错:

'p.gender' must be an aggregate expression or appear in GROUP BY clause

若改为GROUP BY 1, 2,则报错:

'p.kg' must be an aggregate expression or appear in GROUP BY clause

解决方案

你的核心需求是按kg排序后,获取每个id对应的第一行数据,直接用GROUP BY无法实现,因为GROUP BY是聚合分组逻辑,而非筛选指定顺序的行。正确做法是使用窗口函数ROW_NUMBER()标记分组内的行顺序:

SELECT id, gender, kg
FROM (
    SELECT 
        p.id,
        p.gender,
        p.kg,
        ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY p.kg) AS row_num
    FROM patient p
) t
WHERE t.row_num = 1;

逻辑说明

  1. 子查询中,PARTITION BY p.id将数据按id分组
  2. ORDER BY p.kg确保每个分组内的行按kg从小到大排序
  3. ROW_NUMBER()为每个分组内的行分配序号,最小kg的行序号为1
  4. 外层查询筛选出序号为1的行,即每个id对应的最小kg记录

如果你的数据库支持FETCH FIRST WITH TIES(比如PostgreSQL、SQL Server),也可以用更简洁的写法:

SELECT p.id, p.gender, p.kg
FROM patient p
ORDER BY ROW_NUMBER() OVER (PARTITION BY p.id ORDER BY p.kg)
FETCH FIRST 1 ROW WITH TIES;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 20:50:35