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

SQL Server 2017能否对两列分组?如何获取与UserID1聊天用户的最后消息

问题1解答:SQL Server 2017中能否对两列应用GROUP BY?

完全可以!GROUP BY子句支持同时指定多个列,这是SQL的标准特性,SQL Server 2017当然也支持。当你对多列使用GROUP BY时,数据库会将所有指定列的组合值相同的行归为一组,之后就能对每组使用聚合函数(比如COUNT、MAX、SUM等)做统计计算。举个简单的示例:

SELECT MessageCreatorUserID, MessageRecieverUserID, COUNT(*) AS MessageCount
FROM Messages
GROUP BY MessageCreatorUserID, MessageRecieverUserID;

这个查询会按发送者和接收者的组合分组,统计每对用户之间的消息总数。

问题2解答:获取与UserID 1聊天的用户的最后一条消息

针对你给出的消息表结构和数据,我们需要先定位所有和UserID 1有过互动的用户(不管1是消息发送方还是接收方),再找出每个用户与1之间的最后一条消息。下面提供两种实现方式,其中包含你要求的GROUP BY用法:

方法1:基于GROUP BY的分步查询

步骤1:整理聊天伙伴关系

先筛选出所有和1相关的消息,并把聊天伙伴的ID统一提取到单独列中:

SELECT
    CASE
        WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
        ELSE MessageCreatorUserID
    END AS ChatPartnerID,
    MessageID,
    Message,
    CreatedAt,
    MessageCreatorUserID,
    MessageRecieverUserID
FROM Messages
WHERE MessageCreatorUserID = 1 OR MessageRecieverUserID = 1;

步骤2:用GROUP BY获取每个伙伴的最后消息时间

分组每个聊天伙伴,拿到他们和1聊天的最晚消息时间:

SELECT
    ChatPartnerID,
    MAX(CreatedAt) AS LastMessageTime
FROM (
    SELECT
        CASE
            WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
            ELSE MessageCreatorUserID
        END AS ChatPartnerID,
        CreatedAt
    FROM Messages
    WHERE MessageCreatorUserID = 1 OR MessageRecieverUserID = 1
) AS PartnerMessages
GROUP BY ChatPartnerID;

步骤3:关联原表获取完整消息详情

将上面的结果和原表关联,就能拿到每个聊天伙伴的最后一条消息:

SELECT
    m.MessageID,
    m.Message,
    m.MessageCreatorUserID,
    m.MessageRecieverUserID,
    m.CreatedAt,
    CASE
        WHEN m.MessageCreatorUserID = 1 THEN m.MessageRecieverUserID
        ELSE m.MessageCreatorUserID
    END AS ChatPartnerID
FROM Messages m
INNER JOIN (
    SELECT
        CASE
            WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
            ELSE MessageCreatorUserID
        END AS ChatPartnerID,
        MAX(CreatedAt) AS LastMessageTime
    FROM Messages
    WHERE MessageCreatorUserID = 1 OR MessageRecieverUserID = 1
    GROUP BY CASE
        WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
        ELSE MessageCreatorUserID
    END
) AS LastMessages ON 
    (CASE WHEN m.MessageCreatorUserID = 1 THEN m.MessageRecieverUserID ELSE m.MessageCreatorUserID END) = LastMessages.ChatPartnerID
    AND m.CreatedAt = LastMessages.LastMessageTime
ORDER BY m.CreatedAt DESC;

方法2:用窗口函数简化实现(更高效)

如果不想嵌套多层子查询,也可以用ROW_NUMBER()窗口函数实现,写法更简洁:

SELECT *
FROM (
    SELECT
        MessageID,
        Message,
        MessageCreatorUserID,
        MessageRecieverUserID,
        CreatedAt,
        CASE
            WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
            ELSE MessageCreatorUserID
        END AS ChatPartnerID,
        ROW_NUMBER() OVER (PARTITION BY 
            CASE
                WHEN MessageCreatorUserID = 1 THEN MessageRecieverUserID
                ELSE MessageCreatorUserID
            END 
            ORDER BY CreatedAt DESC) AS RowNum
    FROM Messages
    WHERE MessageCreatorUserID = 1 OR MessageRecieverUserID = 1
) AS RankedMessages
WHERE RowNum = 1
ORDER BY CreatedAt DESC;

这个查询会给每个聊天伙伴的消息按时间倒序排名,取排名为1的那条(也就是最后一条消息)。

针对你的示例数据,运行上述查询会得到以下结果:

  • 聊天伙伴4的最后一条消息是ID1的HI
  • 聊天伙伴3的最后一条消息是ID5的hii
  • 聊天伙伴2的最后一条消息是ID4的Thanks

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 03:54:23