SQL 如何在查询中生成序列号?

9次阅读

sql中生成序列号主要靠窗口函数ROW_NUMBER(),它按ORDER BY指定顺序为每行分配严格连续的唯一编号;支持PARTITION BY分组内独立编号;与RANK()、DENSE_RANK()不同,ROW_NUMBER()不处理重复值,始终连续递增。

SQL 如何在查询中生成序列号?

SQL 中生成序列号主要靠窗口函数 ROW_NUMBER(),它能按指定顺序为每一行分配唯一递增编号,不依赖表中现有字段,也不修改数据。

用 ROW_NUMBER() 生成基础序列号

最常用方式是配合 OVER() 子句。ORDER BY 是必需的,否则语法报错;通常按某列排序来定义“顺序”:

SELECT    ROW_NUMBER() OVER (ORDER BY id) AS seq_no,   name,    score FROM students;

结果中 seq_no 从 1 开始,按 id 升序连续编号。注意:即使 id 本身不连续(如缺 3、5),ROW_NUMBER() 仍输出 1,2,3,4…

按分组生成独立序列号

PARTITION BY 可在每个组内重新计数。比如给每个班级的学生单独排号:

SELECT    class,   ROW_NUMBER() OVER (PARTITION BY class ORDER BY score DESC) AS rank_in_class,   name,    score FROM students;

每个班级内,分数最高的学生 rank_in_class = 1,依次类推。不同班级的序号互不影响。

与其他编号函数的区别

容易混淆的是 RANK()DENSE_RANK()

  • ROW_NUMBER():严格连续,相同值也给不同序号(如 1,2,3)
  • RANK():跳过重复名次(如分数并列第1 → 下一个是第3)
  • DENSE_RANK():不跳过(如并列第1 → 下一个是第2)

要纯“序号”而非“排名”,必须用 ROW_NUMBER()

不支持窗口函数的老版本怎么办?

mysql 5.7 或更早、SQL Server 2005 以前等不支持 OVER 的环境,可用变量模拟:

SET @row := 0; SELECT    @row := @row + 1 AS seq_no,   name,    score FROM students ORDER BY id;

注意:必须显式 ORDER BY 保证顺序,且变量赋值和查询需在同一语句中(或用子查询包装)。这种方式可读性差、并发不安全,仅作兼容方案。

text=ZqhQzanResources