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

GROUP BY子句问题:按BookingID和Status分组的字段报错解决方法

搞定分组取最新行的问题,不用把Total/Duration加进GROUP BY!

我太懂你这个困扰了——SQL的聚合规则就是这么严格:SELECT里的非聚合字段要么进GROUP BY,要么被聚合函数包起来,但咱们要的是每个分组里最新那一行的原始Total、Duration,根本不想把它们当分组键对吧?

给你几个实用的解决方案,覆盖不同数据库场景:

方法1:用ROW_NUMBER()窗口函数(最推荐,大部分数据库都支持)

窗口函数可以给每个分组内的行按时间排序,标记出最新的那一行,之后筛选标记为1的就行,完美绕开GROUP BY的限制:

SELECT 
    BookingID,
    Status,
    DateTimeCreatedRealTime,
    Total,
    Duration
FROM (
    SELECT 
        *,
        -- 按BookingID和Status分组,每组内按时间倒序排,给最新行标1
        ROW_NUMBER() OVER(
            PARTITION BY BookingID, Status 
            ORDER BY DateTimeCreatedRealTime DESC
        ) AS row_rank
    FROM BookingTotalAuditTrail
) AS ranked_data
WHERE row_rank = 1;

要是同一个分组里有好几行时间完全相同的最新记录,你想都保留的话,把ROW_NUMBER()换成RANK()就行。

方法2:子查询关联(兼容老版本数据库)

如果你的数据库还不支持窗口函数(比如MySQL 5.x),那就先找出每个分组的最新时间,再关联原表拿对应行的字段:

SELECT 
    main.BookingID,
    main.Status,
    main.DateTimeCreatedRealTime,
    main.Total,
    main.Duration
FROM BookingTotalAuditTrail main
INNER JOIN (
    -- 先拿到每个分组的最新时间
    SELECT 
        BookingID,
        Status,
        MAX(DateTimeCreatedRealTime) AS latest_time
    FROM BookingTotalAuditTrail
    GROUP BY BookingID, Status
) AS latest_times 
    ON main.BookingID = latest_times.BookingID
    AND main.Status = latest_times.Status
    AND main.DateTimeCreatedRealTime = latest_times.latest_time;

注意哦,这个方法会返回同一分组里所有时间等于最新时间的行,要是你只想拿一行,就得再加个筛选条件。

方法3:TOP 1 WITH TIES(仅SQL Server可用)

要是你用的是SQL Server,还有个更简洁的写法:

SELECT TOP 1 WITH TIES
    BookingID,
    Status,
    DateTimeCreatedRealTime,
    Total,
    Duration
FROM BookingTotalAuditTrail
ORDER BY ROW_NUMBER() OVER(PARTITION BY BookingID, Status ORDER BY DateTimeCreatedRealTime DESC);

TOP 1 WITH TIES会自动把所有排序后序号为1的行都返回,省得写子查询啦。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 08:12:27