Sql Server中Row_Number()函数

本文详细介绍SQL中的窗口函数ROW_NUMBER(), RANK(), DENSE_RANK(), NTILE()的使用方法,通过实例展示如何对数据进行排序、分组、编号,以及如何进行高效的数据分析和处理。
摘要由CSDN通过智能技术生成

1.使用row_number()函数进行编号:如

select email,customerID, ROW_NUMBER() over(order by psd) as rows from QT_Customer
  •  

原理:先按psd进行排序,排序完后,给每条数据进行编号。

2.在订单中按价格的升序进行排序,并给每条记录进行排序

代码如下:

select DID,customerID,totalPrice,ROW_NUMBER() over(order by totalPrice) as rows from OP_Order
  •  

3.统计出每一个各户的所有订单并按每一个客户下的订单的金额 升序排序,同时给每一个客户的订单进行编号。这样就知道每个客户下几单了。

如图:
这里写图片描述

代码如下:

select ROW_NUMBER() over(partition by customerID  order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order
  •  

4.统计每一个客户最近下的订单是第几次下的订单。
这里写图片描述

代码如下:

with tabs as
(
select ROW_NUMBER() over(partition by customerID  order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order
 )
 select MAX(rows) as '下单次数',customerID from tabs group by customerID
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

5.统计每一个客户所有的订单中购买的金额最小,而且并统计改订单中,客户是第几次购买的。

如图:
这里写图片描述

上图:rows表示客户是第几次购买。

思路:利用临时表来执行这一操作

1.先按客户进行分组,然后按客户的下单的时间进行排序,并进行编号。

2.然后利用子查询查找出每一个客户购买时的最小价格。

3.根据查找出每一个客户的最小价格来查找相应的记录。

代码如下:

with tabs as
(
select ROW_NUMBER() over(partition by customerID  order by insDT) as rows,customerID,totalPrice, DID from OP_Order
 )
 select * from tabs
 where totalPrice in 
(
 select MIN(totalPrice)from tabs group by customerID
)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

5.筛选出客户第一次下的订单。

思路。利用rows=1来查询客户第一次下的订单记录。

代码如下:

with tabs as
 (
 select ROW_NUMBER() over(partition by customerID  order by insDT) as rows,* from OP_Order
 )
 select * from tabs where rows = 1

 select * from OP_Order
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.rows_number()可用于分页

思路:先把所有的产品筛选出来,然后对这些产品进行编号。然后在where子句中进行过滤。

7.注意:在使用over等开窗函数时,over里头的分组及排序的执行晚于“where,group by,order by”的执行。

如下代码:

select ROW_NUMBER() over(partition by customerID  order by insDT) as rows, customerID,totalPrice, DID  from OP_Order where insDT>'2011-07-22'
  • 1

以上代码是先执行where子句,执行完后,再给每一条记录进行编号。


SqlServer四种排序:ROW_NUMBER()/RANK()/DENSE_RANK()/ntile() over()

首先,我们创建一些测试数据。

if OBJECT_ID('Tempdb.dbo.#Tmp') is not null
    drop table #Tmp
create table #Tmp
(
name nvarchar(10)
)

insert into #Tmp
select N'张三'
union
select N'李四'
union 
select N'王五'
union 
select N'赵六'
union
select N'朱七'
union
select N'王八'
union all
select N'张三'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

最后一个union用union all,因为我们多一行”张三”。

一、ROW_NUMBER() over(partition by columnname order by columnname)

select ROW_NUMBER()over(order by name) as num,* from #Tmp
  • 1

可以得到按name排序的结果集。
这里写图片描述

ROW_NUMBER() over()还有一种用法,可以针对某列进行分组排序。

下面结果可以看到张三有1和2两个排序,而其他的名字排序都只有1。

select ROW_NUMBER()over(partition by name order by name) as num,* from #Tmp
  • 1

这里写图片描述

二、RANK()over(order by columnname)

大家可以从下面的结果集看到,结果集少了5的编号,而有两个4的编号,然后直接跳到编号6。

select RANK()over(order by name),* from #Tmp
  • 1

这里写图片描述

三、DENSE_RANK()over(order by columnname)

select DENSE_RANK()over(order by name),* from #Tmp
  • 1

执行Sql后发现,下面的结果集有2个编号4的行,紧接着就是编号5的行。

DENSE_RANK()函数和RANK()函数差不多。

RANK()函数不管分几组,最后的编号一定和行数相同。

DENSE_RANK()函数最后的编号和分组的数目有关。

这里写图片描述

四、NTILE()OVER(ORDER BY COLUMNNAME)

select NTILE(2)over(order by name),* from #Tmp
select NTILE(3)over(order by name),* from #Tmp
  • 1
  • 2

NTILE后面的数字,是要把查询得到的结果平均分为几组。
如下图分为2和3组。
如果行数平均划分后还有余行,那么就把行分在最前面的几组上。
比如我们的结果有7行,要分为3组。
那么第一组3行,第二组2行,第三组2行。
如果我们结果有14行,平均分为3组。
那么第一组5行,第二组5行,第三组4行。
依此类推。

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值