ROW_NUMBER() OVER函数的基本用法
来源:互联网 发布:pt 90 樱井知香 ed2k 编辑:程序博客网 时间:2024/05/16 18:10
ROW_NUMBER() OVER函数的基本用法用法
转自:http://www.cnblogs.com/icebutterfly/archive/2009/08/05/1539657.html
语法:ROW_NUMBER() OVER(PARTITION BY COLUMN ORDER BY COLUMN)
简单的说row_number()从1开始,为每一条分组记录返回一个数字,这里的ROW_NUMBER() OVER (ORDER BY xlh DESC) 是先把xlh列降序,再为降序以后的没条xlh记录返回一个序号。
示例:
xlh row_num
1700 1
1500 2
1085 3
710 4
row_number() OVER (PARTITION BY COL1 ORDER BY COL2) 表示根据COL1分组,在分组内部根据 COL2排序,而此函数计算的值就表示每组内部排序后的顺序编号(组内连续的唯一的)
实例:
初始化数据
create table employee (empid int ,deptid int ,salary decimal(10,2))
insert into employee values(1,10,5500.00)
insert into employee values(2,10,4500.00)
insert into employee values(3,20,1900.00)
insert into employee values(4,20,4800.00)
insert into employee values(5,40,6500.00)
insert into employee values(6,40,14500.00)
insert into employee values(7,40,44500.00)
insert into employee values(8,50,6500.00)
insert into employee values(9,50,7500.00)
数据显示为
empid deptid salary
----------- ----------- ---------------------------------------
1 10 5500.00
2 10 4500.00
3 20 1900.00
4 20 4800.00
5 40 6500.00
6 40 14500.00
7 40 44500.00
8 50 6500.00
9 50 7500.00
需求:根据部门分组,显示每个部门的工资等级
预期结果:
empid deptid salary rank
----------- ----------- --------------------------------------- --------------------
1 10 5500.00 1
2 10 4500.00 2
4 20 4800.00 1
3 20 1900.00 2
7 40 44500.00 1
6 40 14500.00 2
5 40 6500.00 3
9 50 7500.00 1
8 50 6500.00 2
SQL脚本:
SELECT *, Row_Number() OVER (partition by deptid ORDER BY salary desc) rank FROM employee
转自:http://www.cnblogs.com/digjim/archive/2006/09/20/509344.html
我们知道,SQL Server 2005和SQL Server 2000 相比较,SQL Server 2005有很多新特性。这篇文章我们要讨论其中的一个新函数Row_Number()。数据库管理员和开发者已经期待这个函数很久了,现在终于等到了!
通常,开发者和管理员在一个查询里,用临时表和列相关的子查询来计算产生行号。现在SQL Server 2005提供了一个函数,代替所有多余的代码来产生行号。
我们假设有一个资料库[EMPLOYEETEST],资料库中有一个表[EMPLOYEE],你可以用下面的脚本来产生资料库,表和对应的数据。
USE [MASTER]
GO
IF EXISTS (SELECT NAME FROM SYS.DATABASES WHERE NAME = N'EMPLOYEE TEST')DROP DATABASE [EMPLOYEE TEST]GO
CREATE DATABASE [EMPLOYEE TEST]GO
USE [EMPLOYEE TEST]GO
IF EXISTS SELECT * FROM SYS.OBJECTS HERE OBJECT_ID = OBJECT_ID(N'[DBO].[EMPLOYEE]') AND TYPE IN (N'U'))
DROP TABLE [DBO].[EMPLOYEE]
GO
CREATE TABLE EMPLOYEE (EMPID INT, FNAME VARCHAR(50),LNAME VARCHAR(50))GO
INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (2021110, 'MICHAEL', 'POLAND')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (2021110, 'MICHAEL', 'POLAND')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (2021115, 'JIM', 'KENNEDY')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (2121000, 'JAMES', 'SMITH')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (2011111, 'ADAM', 'ACKERMAN')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (3015670, 'MARTHA', 'LEDERER')INSERT INTO EMPLOYEE (EMPID, FNAME, LNAME) VALUES (1021710, 'MARIAH', 'MANDEZ')GO
我们可以用下面的脚本查询EMPLOYEE表。
SELECT EMPID, RNAME, LNAME FROM EMPLOYEE
这个查询的结果应该如图1.0
2021110
MICHAEL
POLAND
2021110
MICHAEL
POLAND
2021115
JIM
KENNEDY
2121000
JAMES
SMITH
2011111
ADAM
ACKERMAN
3015670
MARTHA
LEDERER
1021710
MARIAH
MANDEZ
图1.0
在SQL Server 2005,要根据这个表中的数据产生行号,我通常使用下面的查询。
SELECT ROWID=IDENTITY(int,1,1) , EMPID, FNAME, LNAME INTO EMPLOYEE2 FROM EMPLOYEE ORDER BY EMPID
这个查询创建了一个新的表,用identify函数来产生行号。我们用下面的查询来看看这个表的数据。
SELECT ROWID, EMPID, FNAME, LNAME FROM EMPLOYEE2
上面的查询结果如图1.1
1
1021710
MARIAH
MANDEZ
2
2011111
ADAM
ACKERMAN
3
2021110
MICHAEL
POLAND
4
2021110
MICHAEL
POLAND
5
2021115
JIM
KENNEDY
6
2121000
JAMES
SMITH
7
3015670
MARTHA
LEDERER
图1.1
这个查询结果很明显EMP=2021110的行是重复的数据。
要删除EMPID=2021110的重复数据,我们必须在EMPLOYEE2表中删除,不能直接在EMPLOYEE中删除。
SQL Server 2005提供了一个新的函数(Row_Number())来产生行号。我们可以使用这个新函数来删除原来表中的重复数据,只用通常的表达方式再加上Row_Number()函数。
让我们用Row_Number()函数根据EMPID来产生ROWID。
SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE
上面的查询结果如图1.2
1
1021710
MARIAH
MANDEZ
2
2011111
ADAM
ACKERMAN
3
2021110
MICHAEL
POLAND
4
2021110
MICHAEL
POLAND
5
2021115
JIM
KENNEDY
6
2121000
JAMES
SMITH
7
3015670
MARTHA
LEDERER
图1.2
在这个结果中,我们可以区别EMPID是2021110的重复数据。
我们可以用通用表查询表达式和Row_Numner()函数来选出重复的那行数据。
WITH [EMPLOYEE ORDERED BY ROWID] AS
(SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE)
SELECT * FROM [EMPLOYEE ORDERED BY ROWID] WHERE ROWID =4
上面的查询结果如图1.3
4
2021110
MICHAEL
POLAND
图1.3
这一行重复的数据可以用下面这个通用表和Row_Number()函数来删除。
WITH [EMPLOYEE ORDERED BY ROWID] AS
(SELECT ROW_NUMBER() OVER (ORDER BY EMPID ASC) AS ROWID, * FROM EMPLOYEE)
DELETE FROM [EMPLOYEE ORDERED BY ROWID] WHERE ROWID =4
删除以后,我们可以用下面的查询语句看一下结果。
SELECT * FROM EMPLOYEE
这个查询结果如图1.4
2021110
MICHAEL
POLAND
2021115
JIM
KENNEDY
2121000
JAMES
SMITH
2011111
ADAM
ACKERMAN
3015670
MARTHA
LEDERER
1021710
MARIAH
MANDEZ
图 1.4
这里我们可以看到,重复的数据已经被删除了。
总结
在这篇文章中,我们讨论了SQL Server 2005 的新特性Row_Number()函数,还有通常的表表达式,然后如何使用这两个来删除重复的行。
--region 参数定义
(
@OperatorPointCode VARCHAR(32),
@OperatorCode VARCHAR(32),
@PointCode VARCHAR(32),
@SaleBillCode VARCHAR(32)=NULL,
@BatholithNumber VARCHAR(32)=NULL,
@BeginDT DATETIME = NULL,
@EndDT DATETIME = NULL,
@SearchFlag int = null
)
--endregion 参数定义
AS
BEGIN
IF @PointCode IS NULL OR @PointCode =''
SET @PointCode = @OperatorPointCode
IF @BeginDT IS NULL OR @BeginDT=''
SET @BeginDT = GETDATE()
IF @EndDT IS NULL OR @EndDT=''
SET @EndDT = GETDATE()
SET @BeginDT = CAST(LTRIM(STR(YEAR(@BeginDT))) + '-' + LTRIM(STR(MONTH(@BeginDT))) + '-' + LTRIM(STR(DAY(@BeginDT)))+ ' 00:00:00.000' AS DATETIME)
SET @EndDT = DATEADD(day,1,@EndDT)
SET @EndDT = CAST(LTRIM(STR(YEAR(@EndDT))) + '-' + LTRIM(STR(MONTH(@EndDT))) + '-' + LTRIM(STR(DAY(@EndDT)))+ ' 00:00:00.000' AS DATETIME)
SELECT
T1.PointCode AS 网点号,
T1.SaleBillCode AS 销售单号,
T5.BatholithNumber AS 车架号,
T3.ChName AS 客户名称,
T10.RelieveCode AS 发票号码,
T10.RelieveMoney AS 发票金额,
T5.PurchasePriceWithNoTax AS 车辆成本,
-- T11.项目 ,
-- T11.ReserveAmount AS 装饰数量,
-- T11.值 ,
'装潢'+cast(Row_number() over(partition by T1.SaleBillCode order by T5.SaleBillSerialNo) as varchar) +'名称' as 项目,
T11.SparepartsName as 值,
(T5.CarSalePrice-T5.PurchasePrice) AS 单车毛利,
(T5.CarSalePrice-T5.PurchasePrice)/T5.CarSalePrice AS 单车毛利率
FROM
T_CS_CarSaleBill T1
INNER JOIN T_CustomerInfo T2 ON T1.CustomerID = T2.CustomerID
INNER JOIN T_PointCustomer T3 ON T1.PointCode = T3.PointCode AND T1.CustomerID = T3.CustomerID
INNER JOIN T_PointInfo T4 ON T1.PointCode = T4.PointCode
LEFT JOIN T_CS_CarSaleBillDetail T5 ON T1.PointCode = T5.PointCode AND T1.SaleBillCode = T5.SaleBillCode
LEFT JOIN (SELECT PointCode,BillType,BillCode,MAX(Status) Status FROM T_TY_OperateStatusSummaryInfo
GROUP BY PointCode,BillType,BillCode) T6 ON T1.PointCode = T6.PointCode AND T1.SaleBillCode = T6.BillCode AND T6.BillType = 'CarSales'
LEFT JOIN T_TY_StatusChangeInfo T7 ON T6.BillType = T7.BillType AND T6.Status = T7.Status
LEFT JOIN
(
SELECT
T8.PointCode,
T9.BillCode,
T8.SerialNo,
T8.RelieveMoney,
T8.RelieveCode,
T8.RelieveName,
T9.BillType,
T8.RelieveDT
FROM T_TY_InvoiceInfo T8
LEFT JOIN T_TY_InvoiceDetailInfo T9
ON T8.PointCode=T9.PointCode AND T8.SerialNo=T9.SerialNo
)T10
ON T10.BillCode=T1.SaleBillCode AND T10.PointCode=T1.PointCode AND T10.BillType='CarSales'AND T10.RelieveName='车辆发票'
LEFT JOIN
(
SELECT
T12.PointCode,
T12.OriginalBillCode,
T12.OriginalBillSerialNo,
T12.SparepartsID,
T12.SparepartsName ,
T13.PurchasePriceWithTax,
T12.ReserveAmount
FROM
T_CS_CarDecorateDetailInfo T12
INNER JOIN T_SparepartsPointContents T13
ON T12.PointCode=T13.PointCode AND T12.SparepartsID=T13.SparepartsID
)
T11
ON T11.PointCode=T5.PointCode AND T11.OriginalBillCode=T5.SaleBillCode AND T11.OriginalBillSerialNo=T5.SaleBillSerialNo
WHERE
(T1.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection(@PointCode, 1, 1, -1 * ISNULL(@SearchFlag, 0), 1)))
AND (@SaleBillCode IS NULL OR @SaleBillCode='' OR T1.SaleBillCode=@SaleBillCode)
AND (@BatholithNumber IS NULL OR @BatholithNumber='' OR T5.BatholithNumber LIKE '%'+@BatholithNumber+'%')
-- AND (DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) >= @BeginDT AND DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) <= @EndDT)
AND T7.StatusDescription='财务收款'
UNION ALL
SELECT
T1.PointCode AS 网点号,
T1.SaleBillCode AS 销售单号,
T5.BatholithNumber AS 车架号,
T3.ChName AS 客户名称,
T10.RelieveCode AS 发票号码,
T10.RelieveMoney AS 发票金额,
T5.PurchasePriceWithNoTax AS 车辆成本,
-- T11.项目 ,
-- T11.ReserveAmount AS 装饰数量,
-- T11.值 ,
'装潢'+cast(Row_number() over(partition by T1.SaleBillCode order by T5.SaleBillSerialNo) as varchar) +'数量' as 项目,
CAST( T11.ReserveAmount AS VARCHAR) AS 值,
(T5.CarSalePrice-T5.PurchasePrice) AS 单车毛利,
(T5.CarSalePrice-T5.PurchasePrice)/T5.CarSalePrice AS 单车毛利率
FROM
T_CS_CarSaleBill T1
INNER JOIN T_CustomerInfo T2 ON T1.CustomerID = T2.CustomerID
INNER JOIN T_PointCustomer T3 ON T1.PointCode = T3.PointCode AND T1.CustomerID = T3.CustomerID
INNER JOIN T_PointInfo T4 ON T1.PointCode = T4.PointCode
LEFT JOIN T_CS_CarSaleBillDetail T5 ON T1.PointCode = T5.PointCode AND T1.SaleBillCode = T5.SaleBillCode
LEFT JOIN (SELECT PointCode,BillType,BillCode,MAX(Status) Status FROM T_TY_OperateStatusSummaryInfo
GROUP BY PointCode,BillType,BillCode) T6 ON T1.PointCode = T6.PointCode AND T1.SaleBillCode = T6.BillCode AND T6.BillType = 'CarSales'
LEFT JOIN T_TY_StatusChangeInfo T7 ON T6.BillType = T7.BillType AND T6.Status = T7.Status
LEFT JOIN
(
SELECT
T8.PointCode,
T9.BillCode,
T8.SerialNo,
T8.RelieveMoney,
T8.RelieveCode,
T8.RelieveName,
T9.BillType,
T8.RelieveDT
FROM T_TY_InvoiceInfo T8
LEFT JOIN T_TY_InvoiceDetailInfo T9
ON T8.PointCode=T9.PointCode AND T8.SerialNo=T9.SerialNo
)T10
ON T10.BillCode=T1.SaleBillCode AND T10.PointCode=T1.PointCode AND T10.BillType='CarSales'AND T10.RelieveName='车辆发票'
LEFT JOIN
(
SELECT
T12.PointCode,
T12.OriginalBillCode,
T12.OriginalBillSerialNo,
T12.SparepartsID,
T12.SparepartsName ,
T13.PurchasePriceWithTax,
T12.ReserveAmount
FROM
T_CS_CarDecorateDetailInfo T12
INNER JOIN T_SparepartsPointContents T13
ON T12.PointCode=T13.PointCode AND T12.SparepartsID=T13.SparepartsID
)
T11
ON T11.PointCode=T5.PointCode AND T11.OriginalBillCode=T5.SaleBillCode AND T11.OriginalBillSerialNo=T5.SaleBillSerialNo
WHERE
(T1.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection(@PointCode, 1, 1, -1 * ISNULL(@SearchFlag, 0), 1)))
AND (@SaleBillCode IS NULL OR @SaleBillCode='' OR T1.SaleBillCode=@SaleBillCode)
AND (@BatholithNumber IS NULL OR @BatholithNumber='' OR T5.BatholithNumber LIKE '%'+@BatholithNumber+'%')
-- AND (DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) >= @BeginDT AND DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) <= @EndDT)
AND T7.StatusDescription='财务收款'
-- ORDER BY '项目','值'
UNION ALL
SELECT
T1.PointCode AS 网点号,
T1.SaleBillCode AS 销售单号,
T5.BatholithNumber AS 车架号,
T3.ChName AS 客户名称,
T10.RelieveCode AS 发票号码,
T10.RelieveMoney AS 发票金额,
T5.PurchasePriceWithNoTax AS 车辆成本,
-- T11.项目 ,
-- T11.ReserveAmount AS 装饰数量,
-- T11.值 ,
'装潢'+cast(Row_number() over(partition by T1.SaleBillCode order by T5.SaleBillSerialNo) as varchar) +'成本' as 项目,
CAST( T11.PurchasePriceWithTax AS VARCHAR) AS 值,
(T5.CarSalePrice-T5.PurchasePrice) AS 单车毛利,
(T5.CarSalePrice-T5.PurchasePrice)/T5.CarSalePrice AS 单车毛利率
FROM
T_CS_CarSaleBill T1
INNER JOIN T_CustomerInfo T2 ON T1.CustomerID = T2.CustomerID
INNER JOIN T_PointCustomer T3 ON T1.PointCode = T3.PointCode AND T1.CustomerID = T3.CustomerID
INNER JOIN T_PointInfo T4 ON T1.PointCode = T4.PointCode
LEFT JOIN T_CS_CarSaleBillDetail T5 ON T1.PointCode = T5.PointCode AND T1.SaleBillCode = T5.SaleBillCode
LEFT JOIN (SELECT PointCode,BillType,BillCode,MAX(Status) Status FROM T_TY_OperateStatusSummaryInfo
GROUP BY PointCode,BillType,BillCode) T6 ON T1.PointCode = T6.PointCode AND T1.SaleBillCode = T6.BillCode AND T6.BillType = 'CarSales'
LEFT JOIN T_TY_StatusChangeInfo T7 ON T6.BillType = T7.BillType AND T6.Status = T7.Status
LEFT JOIN
(
SELECT
T8.PointCode,
T9.BillCode,
T8.SerialNo,
T8.RelieveMoney,
T8.RelieveCode,
T8.RelieveName,
T9.BillType,
T8.RelieveDT
FROM T_TY_InvoiceInfo T8
LEFT JOIN T_TY_InvoiceDetailInfo T9
ON T8.PointCode=T9.PointCode AND T8.SerialNo=T9.SerialNo
)T10
ON T10.BillCode=T1.SaleBillCode AND T10.PointCode=T1.PointCode AND T10.BillType='CarSales'AND T10.RelieveName='车辆发票'
LEFT JOIN
(
SELECT
T12.PointCode,
T12.OriginalBillCode,
T12.OriginalBillSerialNo,
T12.SparepartsID,
T12.SparepartsName ,
T13.PurchasePriceWithTax,
T12.ReserveAmount
FROM
T_CS_CarDecorateDetailInfo T12
INNER JOIN T_SparepartsPointContents T13
ON T12.PointCode=T13.PointCode AND T12.SparepartsID=T13.SparepartsID
)
T11
ON T11.PointCode=T5.PointCode AND T11.OriginalBillCode=T5.SaleBillCode AND T11.OriginalBillSerialNo=T5.SaleBillSerialNo
WHERE
(T1.PointCode IN (SELECT PointCode FROM DBO.F_GetRelationPointCollection(@PointCode, 1, 1, -1 * ISNULL(@SearchFlag, 0), 1)))
AND (@SaleBillCode IS NULL OR @SaleBillCode='' OR T1.SaleBillCode=@SaleBillCode)
AND (@BatholithNumber IS NULL OR @BatholithNumber='' OR T5.BatholithNumber LIKE '%'+@BatholithNumber+'%')
-- AND (DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) >= @BeginDT AND DATEDIFF(DAY,ISNULL(T1.BusinessDT,'1980-1-1'),GETDATE()) <= @EndDT)
AND T7.StatusDescription='财务收款'
END
- ROW_NUMBER() OVER函数的基本用法用法
- ROW_NUMBER() OVER函数的基本用法用法
- ROW_NUMBER() OVER函数的基本用法用法
- ROW_NUMBER() OVER函数的基本用法用法
- ROW_NUMBER() OVER函数的基本用法用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- ROW_NUMBER() OVER函数的基本用法
- 解决Windows XP中IIS禁止访问连接的用户过多
- Message Queuing(MSMQ)学习之旅(一)——基本概念
- 内存泄漏以及常见的解决方法
- Android中intent启动Activity中intent.setFlags()的作用
- 随想录(程序员和收入)
- ROW_NUMBER() OVER函数的基本用法
- 微软老将Philip Su的离职信:回首12年职场生涯
- Javascript网页破坏游戏
- 【鼠标右键点击桌面图标时,出现资源管理器未响应】
- Android深入浅出教程
- 插入排序——直接插入排序
- 《linux设备驱动程序III》学习---第六章
- 搜狗网址导航产品建议(吐槽版)
- OpenGL中各种坐标系的理解