ROW_NUMBER()在SQL2K5版本中新增,该函数返回结果集分区内行的序列号,每个分区的第一行从 1 开始,连续不间断,后跟OVER BY子句或者PARTITION BY子句
先构造一张表,放一些数据进行,SQL脚本如下
--DROP TABLE T
CREATE TABLE T(GRP_A VARCHAR(20),GRP_B VARCHAR(20),GRP_C VARCHAR(20),VAL INT)
INSERT INTO T(GRP_A,GRP_B,GRP_C,VAL)
SELECT 'a1','b1','c1',10 union all
SELECT 'a1','b1','c2',20 union all
SELECT 'a1','b2','c2',30 union all
SELECT 'a1','b2','c3',40 union all
SELECT 'a1','b2','c3',50 union all
SELECT 'a2','b3','c3',12 union all
SELECT 'a2','b3','c3',22 union all
SELECT 'a2','b3','c3',32
SELECT * FROM T
执行查询后的结果:
GRP_A GRP_B GRP_C VAL
-------------------- -------------------- -------------------- -----------
a1 b1 c1 10
a1 b1 c2 20
a1 b2 c2 30
a1 b2 c3 40
a1 b2 c3 50
a2 b3 c3 12
a2 b3 c3 22
a2 b3 c3 32
(8 行受影响)
ORDER BY子句
如果单独使用ORDER BY子句,则整个结果集为一个分区,
下边的SQL语句单使用了ORDER BY子句,先按GRP_A排序,然后根据排序后的结果额外生成一连续自增的NUM列
SELECT
*,
ROW_NUMBER()OVER(ORDER BY GRP_A) AS NUM
FROM T
结果集如下,不算复杂啊:
GRP_A GRP_B GRP_C VAL NUM
-------------------- -------------------- -------------------- ----------- --------------------
a1 b1 c1 10 1
a1 b1 c2 20 2
a1 b2 c2 30 3
a1 b2 c3 40 4
a1 b2 c3 50 5
a2 b3 c3 12 6
a2 b3 c3 22 7
a2 b3 c3 32 8
(8 行受影响)
跟不加ROW_NUMBER函数的区别就是增加了最后那一列,NUM,其值是递增的,增量为1
同理可以按照其它字段排序,如VAL,或者GRP_B,GRP_C等,列名不变,列值不变,变的是其它列的顺序
这个查询仅有一个分区,就是整个结果集,整个结果集内有这么一列,自增NUM列,可以用来分页或者啥的啥的
没有什么特别之处,ORDER BY 跟普通的ORDER BY 类似,也可以有多个列的排序,如:
SELECT
*,
ROW_NUMBER()OVER(ORDER BY GRP_A ASC,GRP_B DESC,VAL ASC) AS NUM
FROM T
最终影响的还是结果集中除NUM列外的其它数据的排序
PARTITION BY XXX ORDER BY YYY子句
使用PARTITION BY子句后,结果集就会按照该字段进行分区,这时候仍然要使用ORDER BY子句,影响的是分区内的排序,然后在每个分区内生成从1开始的自增列:
SELECT
*,
ROW_NUMBER()OVER(PARTITION BY GRP_A ORDER BY VAL) AS NUM
FROM T
这时候结果集发生变化了,必须得发生!
GRP_A GRP_B GRP_C VAL NUM
-------------------- -------------------- -------------------- ----------- --------------------
a1 b1 c1 10 1
a1 b1 c2 20 2
a1 b2 c2 30 3
a1 b2 c3 40 4
a1 b2 c3 50 5
a2 b3 c3 12 1
a2 b3 c3 22 2
a2 b3 c3 32 3
(8 行受影响)
SELECT * FROM (SELECT
*,
ROW_NUMBER()OVER(ORDER BY VAL) AS NUM
FROM T) AS SOMETABLENAME
WHERE NUM BETWEEN 1 AND 5
相对应的结果集
GRP_A GRP_B GRP_C VAL NUM
-------------------- -------------------- -------------------- ----------- --------------------
a1 b1 c1 10 1
a2 b3 c3 12 2
a1 b1 c2 20 3
a2 b3 c3 22 4
a1 b2 c2 30 5
(5 行受影响)