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

SQL Server新手求助:不使用ORDER BY子句生成DENSE_RANK()的方法

解决SQL Server无ORDER BY的DENSE_RANK需求

嘿,作为SQL Server新手能想到用DENSE_RANK()已经很赞啦!不过你提到要去掉ORDER BY子句,得先理清一个关键点:排名函数(比如DENSE_RANK)本身依赖排序规则来确定排名顺序——你想要的排名其实是按照Report No在数据里首次出现的先后顺序生成的对吧?

核心思路

因为数据库默认返回的行顺序是不确定的(没有ORDER BY时,SQL Server不保证行的输出顺序),所以我们得先给每行分配一个能代表其出现顺序的序号,再基于这个序号来计算排名。这里可以用ROW_NUMBER()配合ORDER BY (SELECT NULL)来获取数据的默认存储顺序(注意:如果表有聚集索引,这个顺序是稳定的;如果没有,后续数据变更可能影响顺序,最好用明确的业务列替代,比如创建时间、自增ID)。

具体SQL示例

假设你的表名为Reports,存储报表编号的列是ReportNo,可以用CTE(公共表表达式)来实现:

-- 第一步:给每行分配一个代表出现顺序的序号
WITH OrderedReports AS (
    SELECT 
        ReportNo,
        ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS RowSeq
    FROM Reports
),
-- 第二步:基于序号计算DENSE_RANK
RankedReports AS (
    SELECT 
        ReportNo,
        DENSE_RANK() OVER(ORDER BY RowSeq) AS Rank
    FROM OrderedReports
)
-- 输出最终结果
SELECT ReportNo, Rank
FROM RankedReports;

补充说明

  • ORDER BY (SELECT NULL)是SQL Server的一个小技巧,让ROW_NUMBER()按照数据的默认存储顺序生成序号,这样相同的ReportNo会因为首次出现的顺序相同而获得相同的排名,完全匹配你给出的示例效果。
  • 如果你的表有类似CreateTime(创建时间)或者ID(自增主键)这类能确定顺序的列,把(SELECT NULL)替换成这个列会更可靠,比如ORDER BY CreateTime,避免默认存储顺序变化带来的排名波动。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 08:16:49