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

如何筛选Jack(a_id=2)参与的所有房间的最后聊天消息?

解决Jack参与房间的最后聊天消息查询问题

你的核心问题是没有先筛选出Jack参与的房间范围,直接对全表使用distinct on导致结果包含了Jack未参与的房间。以下两种方法都能解决问题,包括你提到的partition窗口函数方案:

方法一:改进distinct on写法(PostgreSQL专属)

先通过CTE获取Jack所有参与的房间,再在这些房间内取最新消息:

WITH jack_rooms AS (
    -- 先拿到Jack参与过的所有房间ID
    SELECT DISTINCT r_id FROM chat WHERE a_id = 2
)
SELECT DISTINCT ON (c.r_id) c.*
FROM chat c
JOIN jack_rooms jr ON c.r_id = jr.r_id
ORDER BY c.r_id, c.date DESC;

执行后只会返回r_id=77的最新消息,符合你的需求。

方法二:使用窗口函数PARTITION BY(标准SQL,兼容性更强)

用ROW_NUMBER()给每个房间的消息按日期倒序排名,再筛选排名第一的记录:

WITH ranked_messages AS (
    SELECT 
        *,
        -- 按房间分组,日期倒序排名
        ROW_NUMBER() OVER (PARTITION BY r_id ORDER BY date DESC) AS rn
    FROM chat
    -- 仅保留Jack参与的房间
    WHERE r_id IN (SELECT DISTINCT r_id FROM chat WHERE a_id = 2)
)
SELECT a_id, name, r_id, message, date
FROM ranked_messages
WHERE rn = 1;

为什么之前的写法出错?

你之前的SQL没有添加房间过滤条件,distinct on (r_id)会遍历全表的所有房间,自然会包含Jack从未参与的r_id=79房间的最新消息。只要先限定房间范围,两种写法都能得到正确结果。

内容的提问来源于stack exchange,提问作者qubicswap.com

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 20:30:51