SQL 2005的行号(转)

本文介绍并演示了SQL中ROW_NUMBER(), RANK() 和 NTILE()等窗口函数的应用案例。通过具体场景展示了如何使用这些函数进行数据排名、分组及分区处理。
select CAST(ROW_NUMBER() OVER(order by Name) AS varchar(32)) AS rowindex可以将行号取出来转换成varchar型的显示在页面上

1
ROW_NUMBER
SELECT ProductID, Name, Price, 
ROW_NUMBER() OVER(ORDER BY Price DESC) As PriceRank
FROM Products
ProductID Name Price PriceRank
8Desk495.00001
10Executive Chair295.00002
9Chair125.00003
5Mouse14.95004
6Mousepad9.99005
11Scissors8.50006
4Stapler7.95007
3Binder1.95008
...
SELECT c.Name, o.DateOrdered, tab.TotalOrderAmount, 
ROW_NUMBER() OVER (PARTITION BY c.CustomerID ORDER BY TotalOrderAmount DESC) AS BestCustomer
FROM vwTotalAmountBilledPerOrder AS tab
INNER JOIN Orders AS o ON
o.OrderID = tab.OrderID
INNER JOIN Customers AS c ON
c.CustomerID = o.CustomerID
Name DateOrdered TotalOrderAmount BestCustomer
Bob12/1/200512649.99001
Bob12/19/2005265.85002
Tito12/22/200514.95001
Tito12/18/200512.44002
Darren1/2/2006620.00001
Bruce1/5/200614.95001
Bruce1/4/20069.99002
Lee Ann1/3/20068.50001
...

2 RANK

SELECT c.Name, o.DateOrdered, tab.TotalOrderAmount, 
RANK() OVER (ORDER BY TotalOrderAmount DESC) AS BestCustomer
FROM vwTotalAmountBilledPerOrder AS tab
INNER JOIN Orders AS o ON
o.OrderID = tab.OrderID
INNER JOIN Customers AS c ON
c.CustomerID = o.CustomerID
Name DateOrdered TotalOrderAmount BestCustomer
Bob12/1/200512649.99001
Darren1/2/2006620.00002
Bob12/19/2005265.85003
Tito12/22/200514.95004
Bruce1/5/200614.95004
Tito12/18/200512.44006
Bruce1/4/20069.99007
Lee Ann1/3/20068.50008
...

3 NTILE

SELECT ProductID, Name, Price, NTILE(4) OVER (ORDER BY Price DESC) as Quartile
FROM Produts

ProductID Name Price Quartile
8Desk495.00001
10Executive Chair295.00001
9Chair125.00002
5Mouse14.95002
6Mousepad9.99003
11Scissors8.50003
4Stapler7.95004
3Binder1.95004
<think> 嗯,用户现在想了解SQL Server中获取行号的方法。从用户的问题来看,ta应该是在做数据库开发或者数据分析相关工作,需要掌握行号生成技巧来解决具体问题。 用户特意提到"获取行号的方法",说明ta需要的是系统性的解决方案,而不仅仅是简单语法。结合之前提供的三个引用,可以看出用户可能面临多种场景:基础排序编号、随机抽样、数据清理等。虽然用户当前只问了基础方法,但应该预见到ta后续可能会有更复杂的需求。 注意到引用[1]展示了ROW_NUMBER()的基础用法,引用[2]演示了行号用于随机查询的技巧,引用[3]则涉及基于行号的数据删除。这些引用涵盖了主要应用场景,在回答时应该有机整合。 用户没有指定具体场景,所以回答需要分层说明。先从最基础的ROW_NUMBER()讲起,这是最通用的行号生成方法。然后要补充说明其他相关函数的区别,比如RANK()和DENSE_RANK(),避免用户混淆。最后通过典型应用场景展示实用价值,这样能帮助用户举一反三。 特别要注意的是,用户可能被引用[3]中的Oracle语法干扰(使用了rownum别名),需要强调SQL Server必须使用窗口函数,不能直接使用ROWNUM伪列。这点要在回答中明确区分。 生成的问题要覆盖延伸需求:基础语法差异(对比Oracle)、性能影响、分页实现等。用户既然在研究行号,后续很可能遇到分页优化问题,最后一个问题就是为这个铺垫的。 </think> 在 SQL Server 中,最常用且推荐的方法是使用窗口函数 `ROW_NUMBER()` 来获取行号。以下是详细的说明和用法: ### 一、基础方法:`ROW_NUMBER()` **语法**: ```sql SELECT [列名], ROW_NUMBER() OVER (ORDER BY [排序列]) AS RowNum FROM [表名] ``` **功能**: 为结果集的每一行生成唯一递增序号(从1开始),序号基于 `ORDER BY` 指定的顺序。**必须指定 `ORDER BY` 子句**。 **示例**(按员工ID排序生成行号): ```sql SELECT EmployeeID, Name, ROW_NUMBER() OVER (ORDER BY EmployeeID) AS RowNum FROM Employees; ``` 结果示例: | EmployeeID | Name | RowNum | |------------|---------|--------| | 101 | Alice | 1 | | 102 | Bob | 2 | | 103 | Charlie | 3 | --- ### 二、其他行号相关函数(对比说明) | 函数 | 特点 | 示例场景 | |--------------------|----------------------------------------------------------------------|------------------------------| | `RANK()` | 相同值并列排名,后续序号跳过并列数量(如:1,1,3) | 成绩排名(允许并列) | | `DENSE_RANK()` | 相同值并列排名,后续序号连续(如:1,1,2) | 薪资梯队排名 | | `NTILE(n)` | 将数据分为 `n` 组并分配组号 | 数据分桶分析 | **对比示例**: ```sql SELECT Score, ROW_NUMBER() OVER (ORDER BY Score DESC) AS 'RowNum', RANK() OVER (ORDER BY Score DESC) AS 'Rank', DENSE_RANK() OVER (ORDER BY Score DESC) AS 'DenseRank' FROM ExamResults; ``` 输出: | Score | RowNum | Rank | DenseRank | |-------|--------|------|-----------| | 100 | 1 | 1 | 1 | | 100 | 2 | 1 | 1 | | 95 | 3 | 3 | 2 | --- ### 三、关键应用场景 1. **分页查询** 结合 `CTE` 或子查询实现高效分页: ```sql -- 获取第11~20条记录 WITH PagedData AS ( SELECT *, ROW_NUMBER() OVER (ORDER BY CreateTime DESC) AS RowNum FROM Orders ) SELECT * FROM PagedData WHERE RowNum BETWEEN 11 AND 20; ``` 2. **删除历史数据** 保留最新1000条记录(引用[3]的优化方案): ```sql DELETE FROM M_MONI_DATA_HISTORY WHERE ID IN ( SELECT ID FROM ( SELECT ID, ROW_NUMBER() OVER (ORDER BY CreateDate DESC) AS RowNum FROM M_MONI_DATA_HISTORY ) t WHERE t.RowNum > 1000 -- 删除1000条之后的数据 ); ``` 3. **随机抽样**(引用[2]方案优化) 随机选取1条记录: ```sql SELECT * FROM ( SELECT *, ROW_NUMBER() OVER (ORDER BY NEWID()) AS RandomRow FROM Products ) t WHERE t.RandomRow = 1; -- 改为固定值避免多次计算NEWID() ``` --- ### 四、注意事项 1. **性能优化** `ORDER BY` 子句应使用索引列(如主键),否则大数据量表可能导致性能问题。 2. **结果稳定性** 当 `ORDER BY` 列存在重复值时,相同值的行顺序可能随查询变化(除非指定唯一排序列)。 3. **与Oracle区别** SQL Server **不支持** `ROWNUM` 伪列(如Oracle),必须使用 `ROW_NUMBER()` [^1][^3]。 > ⚠️ 注意:`ROW_NUMBER()` 生成的是**查询结果的临时序号**,与物理存储顺序无关。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值