ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

SQL Server 常用分页SQL

2019-08-21 13:05:12  阅读:311  来源: 互联网

标签:分页 FirstName LastName RowNumber Server Start EmailAddress SQL SELECT


原文链接:http://www.cnblogs.com/ebread/p/SQLServer.html

今天无聊和朋友讨论分页,发现网上好多都是错的。网上经常查到的那个Top Not in 或者Max 大部分都不实用,很多都忽略了Order和性能问题。为此上网查了查,顺带把2000和2012版本的也补上了。

先说说网上常见SQL的错误或者说局限问题

select top 10 * 
from table1
where id not in(
    select top 开始的位置 id 
    from table1)

这样的确是可以取到分页数据,但是这是默认排序的,如果要按其中一列排序呢?那order by 加在哪里呢?里外都加,显然不行,外面的Order不起作用,只能嵌套,Oh my god,编程三个Select了,这效率。

为了好用效率高,总体思路还是老老实实的用RowNumber解决,但是SQL2000没有RowNumber,其实我们可以通过临时表自增列搞定,不多说,上例子。

 

SQL 2000 用临时表解决,通过在临时表中增加自增列解决RowNumber。

DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 14000,@End = 14050


CREATE TABLE #employees (RowNumber INT IDENTITY(1,1),
LastName VARCHAR(100),FirstName VARCHAR(100),
EmailAddress VARCHAR(100))


INSERT INTO #employees (LastName, FirstName, EmailAddress)
SELECT LastName, FirstName, EmailAddress 
FROM Employee 
ORDER BY LastName, FirstName, EmailAddress
SELECT LastName, FirstName, EmailAddress 
FROM #employees
WHERE RowNumber > @Start AND RowNumber <= @End


DROP TABLE #employees


GO

  


SQL 2005/2008 由于支持了Row_Number于是通过派生表的方式解决(两个嵌套)

DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 14000,@End = 14050


SELECT LastName, FirstName, EmailAddress
FROM (SELECT LastName, FirstName, EmailAddress,
ROW_NUMBER() OVER (ORDER BY LastName, FirstName, EmailAddress) AS RowNumber
FROM Employee) EmployeePage
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY LastName, FirstName, EmailAddress
GO

  


SQL 2005/2008 或者用CTE的方式实现,和派生表一样,就是好看点,执行计划都一样。

DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 14000,@End = 14050;


WITH EmployeePage AS
(SELECT LastName, FirstName, EmailAddress,
ROW_NUMBER() OVER (ORDER BY LastName, FirstName, EmailAddress) AS RowNumber
FROM Employee)
SELECT LastName, FirstName, EmailAddress
FROM EmployeePage
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY LastName, FirstName, EmailAddress
GO

  


SQL SERVER 2012 比较给力支持了OFFSET,于是一个Select结束战斗

SELECT LastName, FirstName, EmailAddress
FROM Employee
ORDER BY LastName, FirstName, EmailAddress
OFFSET 14000 ROWS
FETCH NEXT 50 ROWS ONLY;

  

 

最后说下,根据老外的文章,在2012里,如果前面加上TOP(50),那么执行计划就会少读很多行数据(读的精准了),提高性能。但是鉴于本人手头没2012也无法测试。至少在2008R2上加不加TOP执行计划都一样。

转载于:https://www.cnblogs.com/ebread/p/SQLServer.html

标签:分页,FirstName,LastName,RowNumber,Server,Start,EmailAddress,SQL,SELECT
来源: https://blog.csdn.net/weixin_30466953/article/details/99951908

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有