一、概念
为结果集的分区中的每一行分配一个连续的整数,行号以每个分区中第一行的行号开头。
语法:
ROW_NUMBER() OVER (
[PARTITION BY partition_expression,...]
ORDER BY sort_expression [ASC| DESC],..
)
- PARTITION BY 子句将结果集化为分区。ROW_NUMBER()函数分别应用于每个分区,并重新初始化每个分区的行号。PARTITION BY 子句是可选的,如果未指定,将整个结果集视为单个分区。
- ORDER BY 子句定义结果集的每个分区中的行的逻辑顺序。该字句是必需的。
注意:
使用over等开窗函数时,over里头的分组及排序的执行晚于“where,group by,order by”的执行。
二、SQLserver实例
1、为每个客户行分配序号:
SELECT ROW_NUMBER() OVER(
ORDER BY first_name ) row_num,
first_name,last_name,city
FROM Customers;
执行结果:
2、按城市分类,给每个客户分配一个顺序整数,当城市改变时,重置数字:
SELECT first_name,last_name,city,
ROW_NUMBER() OVER (
PARTITION BY city
ORDER BY first_name) row_num
FROM Customers
ORDER BY city;
3、使用ROW_NUMBER() 进行分页
假设每页10行,返回第二页(11行到20行)的数据:
WITH cte_customers AS (
SELECT ROW_NUMBER() OVER(
ORDER BY first_name,last_name) row_num,
custrmer_id,first_name,last_name
FROM customers)
SELECT customer_id,first_name,last_name
FROM cte_customers
WHERE row_num >20 AND row_num <=30;
4、统计客户的所有订单中最小金额,并统计客户是第几次购买
思路:先按客户分组,再按下单时间排序,并进行编号
然后查找出每一个客户购买时的最小价格与编号
WITH tabs as (
SELECT ROW_NUMBER() OVER (
PARTITON BY customerid
OEDER BY ordertime ) row_num,
customerid,totalprice
FROM Orders)
select * from tabs where totalprice in (
select MIN(totalprice) from tabs group by customerid
)