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

MSSQL中按分组+最大rowId获取每组最后一条记录的最优查询

解决SQL Server中按分组取每组最后一条记录(基于自增rowId)的最优方案

嘿,这个场景太常见了——用时间戳分组的时候,批量更新很容易导致同一组里多条记录的lastupdate完全一致,原查询就会返回重复结果。好在你有自增的rowId,这可是个精准定位的利器,结合它就能完美解决问题,还能保证性能。下面给你两种最优的实现方式,附性能优化建议:

方案一:分组子查询关联(适合追求极致性能的场景)

这种写法先通过分组拿到每个computername对应的最大rowId,再和原表关联匹配,精准定位每组的最后一条记录:

SELECT t.*
FROM t
INNER JOIN (
    SELECT computername, MAX(rowId) AS max_rowId
    FROM t
    GROUP BY computername
) AS grouped_t 
    ON t.computername = grouped_t.computername 
    AND t.rowId = grouped_t.max_rowId;

性能说明:

只要给表t创建复合索引(computername, rowId),数据库就能直接通过索引快速获取每个分组的最大rowId,不需要扫描全表。这个索引还能加速后续的关联操作,整体性能非常出色。

方案二:ROW_NUMBER()窗口函数(可读性&灵活性拉满)

SQL Server 2005及以后支持窗口函数,这种写法可读性极强,而且如果之后需要取每组前N条记录,改个条件就行:

WITH ranked_records AS (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY computername ORDER BY rowId DESC) AS rn
    FROM t
)
SELECT *
FROM ranked_records
WHERE rn = 1;

性能说明:

同样建议创建复合索引(computername, rowId DESC),数据库可以利用这个索引直接完成分组排序,避免额外的排序开销,效率和方案一不相上下,但代码更易懂。

关键注意点

  • 确保rowId是严格自增且不会被更新的:因为我们依赖它的递增性来判断“最后一条”,如果更新操作会修改rowId,这个逻辑就不成立了(不过自增字段默认是不会被修改的,放心用)。
  • 索引是性能核心:上面提到的复合索引能让两种方案的查询速度提升几个量级,尤其是数据量大的时候,一定要加上。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:24:16