top with ties 必须与 order by 配合使用,用于返回排序后第 n 行值相同的所有记录,实际行数可能超过 n;不支持 offset-fetch,且仅依据 order by 最后字段判断并列。

TOP WITH TIES 不是独立语法,它必须和 ORDER BY 一起用,否则会报错 Incorrect syntax near 'WITH'。它的核心作用就一个:把排序后“挤在边界上”的并列值全捞出来,而不是只取前 N 行物理位置上的记录。
必须搭配 ORDER BY 才能生效
单独写 SELECT TOP 3 WITH TIES * 而不跟 ORDER BY,SQL Server 直接拒绝执行。这不是可选项,是硬性约束。因为 WITH TIES 的逻辑依赖于排序结果——它要对比“第 N 行的排序字段值”,再找所有值相同的行。没有排序,就没有“最后一行”,也就没 tie 可 tied。
常见错误写法:
-
SELECT TOP 3 WITH TIES * FROM StudentScore→ 缺ORDER BY,报错 -
SELECT WITH TIES * FROM StudentScore ORDER BY Score DESC→ 少TOP,报错
TOP 数值只是“锚点”,实际返回行数可能更多
你写 TOP 5 WITH TIES,最终结果可能是 5 行、7 行甚至 12 行——只要第 5 行的 ORDER BY 字段值,在后续行里还重复出现,那些行就全算进来。
比如成绩表里,按 Score DESC 排序后第 5 行是 92 分,而第 6、7、8 行也都是 92 分,那这 4 行(第 5–8 行)都会被返回。
这意味着:
- 不能假设返回行数一定等于
TOP后面的数字 - 如果业务逻辑强依赖“恰好 N 行”,就别用
WITH TIES,改用ROW_NUMBER()+ 子查询或OFFSET-FETCH -
TOP 10 PERCENT WITH TIES同样适用:先算出 10% 对应的行数(向上取整),再把该位置的排序值所有匹配行都拉进来
排序字段重复时,WITH TIES 是唯一稳定方案
当 ORDER BY 字段有重复值,又没加二级排序,TOP N 本身返回结果就不确定——SQL Server 可能每次选不同的“第 N 名”。WITH TIES 消除了这种不确定性:只要排序值相同,就一并包含。
但注意:它不保证这些并列行内部的顺序。比如两个 97 分的学生,谁在前谁在后,仍由 SQL Server 决定,除非你显式加二级排序,例如:
SELECT TOP 3 WITH TIES * FROM StudentScore ORDER BY Score DESC, id ASC
这样至少能让同分学生按 id 排序,提升可预测性。
不能和 OFFSET-FETCH 混用
TOP WITH TIES 和 OFFSET-FETCH 是互斥的。SQL Server 不允许在同一个 SELECT 中同时出现 TOP 和 OFFSET。如果你需要分页 + 并列处理,得换思路:
- 用
ROW_NUMBER()窗口函数先打排名,再用WHERE过滤指定排名范围 - 或者用 CTE 包一层,先取带 ties 的结果,再对结果集做
OFFSET-FETCH - 直接放弃分页,接受一次性拉回所有并列数据——很多报表场景其实更合理
实际用的时候,最常被忽略的是:它只认 ORDER BY 最后一个字段的值。如果排序字段多层嵌套,tie 判断只基于最末那个字段,前面的字段不影响“是否并列”。这点容易误判,尤其在复合排序场景下。











