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

按sender_id分组SQL报错:列需在GROUP BY子句或聚合函数中

这个错误是PostgreSQL(以及其他遵循SQL标准的数据库)的典型限制,我来帮你拆解问题并给出解决方案:

为什么会报错?

当你使用GROUP BY时,数据库要求SELECT列表里所有不是聚合函数(比如MAX()、MIN())的字段,必须出现在GROUP BY子句中。你的SQL里选中了users.first_name、users.last_name等字段,但这些字段既没在GROUP BY里,也没被聚合函数处理——数据库不知道分组后应该取同一sender_id下哪一行的这些值,所以抛出了这个错误。

虽然我们知道同一个sender_id对应唯一的用户信息,但数据库不会自动推断这一点,必须明确告诉它规则。

你的需求分析

从期望输出来看,你想要给接收者ID为4的用户,展示每个发送者的基本信息,以及该发送者的一条聊天内容(每个发送者只显示一条)。结合你的示例数据,应该是取每个发送者的第一条聊天记录(sender5的第一条是hallo,sender6的第一条是whoaa)。

正确的SQL写法

推荐用子查询+关联查询的方式,先定位每个发送者的目标聊天记录,再关联用户表获取信息,这样逻辑更清晰,也能精准拿到你想要的内容:

SELECT 
    u.avatar_url, 
    u.first_name, 
    u.last_name, 
    c.content
FROM 
    users u
JOIN 
    chatting c ON u.id = c.sender_id
-- 子查询:找到每个sender_id对应的第一条聊天记录(用最小的chatting_id判断)
JOIN (
    SELECT sender_id, MIN(chatting_id) AS target_chat_id
    FROM chatting
    WHERE received_id = '4'
    GROUP BY sender_id
) target_chats ON c.chatting_id = target_chats.target_chat_id
WHERE 
    c.received_id = '4';

如果想要每个发送者的最新聊天记录,只需要把子查询里的MIN(chatting_id)改成MAX(chatting_id)即可。

另一种简化写法(仅适用于用户信息与sender_id一一对应)

如果你确定同一个sender_id对应的用户信息完全一致,也可以用聚合函数包裹用户字段,同时保留GROUP BY chatting.sender_id:

SELECT 
    MAX(u.avatar_url) AS avatar_url, 
    MAX(u.first_name) AS first_name, 
    MAX(u.last_name) AS last_name, 
    MIN(c.content) AS content -- 这里用MIN是取第一条内容,若要最新则用MAX(chatting_id)关联更准确
FROM 
    users u
JOIN 
    chatting c ON u.id = c.sender_id
WHERE 
    c.received_id = '4'
GROUP BY 
    c.sender_id;

不过这种方式有局限性:如果用MAX(c.content),只是取内容字符串的最大值,不一定是最新的聊天内容,所以还是第一种子查询的方式更可靠。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:03:25