原文:
SQL点滴16—SQL分页语句总结
今天对分页语句做一个简单的总结,他们大同小异的,只要理解其中一个其他的就很好理解了。
使用top选项
select
top
10
*
from
Orders
a
where
a.orderid
not
in
(
select
top
10
orderid
from
Orders
order
by
orderid)
order
by
a.orderid
使用max函数
这种方法的前提是有唯一值的一个列。
select
top
10
*
from
Orders a
where
a.orderid
>
(
select
MAX
(orderid)
from
(
select
top
10
orderid
from
Orders
order
by
orderid)
as
orderid)
order
by
orderid
使用row_number()
select
*
from
(
select
ROW_NUMBER()
over
(
order
by
orderid)
as
rownumber,
*
from
Orders) myresult
where rownumber between 10 and 20
select top 10 * from ( select ROW_NUMBER() over ( order by orderid) as rownumber, * from Orders) myresult
where rownumber > 10
with OrderedResult as (
select * ,ROW_NUMBER() over ( Order by orderid) as rownumber from Orders)
select * from OrderedResult where rownumber between 10 and 20
where rownumber between 10 and 20
select top 10 * from ( select ROW_NUMBER() over ( order by orderid) as rownumber, * from Orders) myresult
where rownumber > 10
with OrderedResult as (
select * ,ROW_NUMBER() over ( Order by orderid) as rownumber from Orders)
select * from OrderedResult where rownumber between 10 and 20
使用rowcount设置
begin
declare @first_id varchar ( 18 ), @startrow int
set rowcount 10
select @first_id = orderid from Orders order by orderid
select * from Orders where orderid > @first_id order by orderid
set rowcount 0
end
declare @first_id varchar ( 18 ), @startrow int
set rowcount 10
select @first_id = orderid from Orders order by orderid
select * from Orders where orderid > @first_id order by orderid
set rowcount 0
end
使用临时表
begin
declare @pagelowerbound int
declare @pageupperbound int
set @pagelowerbound = 10
set @pageupperbound = 20
create table #pageindex( [ indexid ] int identity ( 1 , 1 ) not null , [ id ] varchar ( 18 ))
declare @sql nvarchar ( 2000 )
set @sql = ' insert into #pageindex([id]) select top ' + CONVERT ( nvarchar , @pageupperbound )
set @sql = @sql + ' orderid from Orders '
execute sp_executesql @sql
select a. * from Orders a inner join #pageindex b on a.orderid = b.id where b.indexid > @pagelowerbound order by b.indexid
drop table #pageindex
end
declare @pagelowerbound int
declare @pageupperbound int
set @pagelowerbound = 10
set @pageupperbound = 20
create table #pageindex( [ indexid ] int identity ( 1 , 1 ) not null , [ id ] varchar ( 18 ))
declare @sql nvarchar ( 2000 )
set @sql = ' insert into #pageindex([id]) select top ' + CONVERT ( nvarchar , @pageupperbound )
set @sql = @sql + ' orderid from Orders '
execute sp_executesql @sql
select a. * from Orders a inner join #pageindex b on a.orderid = b.id where b.indexid > @pagelowerbound order by b.indexid
drop table #pageindex
end
使用动态存SQL语句
一个分页存储过程,支持多表连接的情况。原理还是使用主键。
USE
[
PressErp
]
GO
/*
***** Object: StoredProcedure [dbo].[UP_GetRecordByPageIndex] Script Date: 05/06/2013 22:00:50 *****
*/
SET
ANSI_NULLS
ON
GO
SET
QUOTED_IDENTIFIER
ON
GO
--
用途:分页存储过程(对有主键的表效率极高)
ALTER
PROCEDURE
[
dbo
]
.
[
UP_GetRecordByPageIndex
]
@tblName
varchar
(
255
),
--
表名
@fldName
varchar
(
255
),
--
主键字段名
@PageSize
int
=
10
,
--
页尺寸
@PageIndex
int
=
1
,
--
页码
@IsReCount
bit
=
0
,
--
返回记录总数, 非 0 值则返回
@OrderType
bit
=
0
,
--
设置排序类型, 非 0 值则降序
@strWhere
varchar
(
1000
)
=
''
--
查询条件 (注意: 不要加 where)
AS
declare
@strSQL
varchar
(
6000
)
--
主语句
declare
@strTmp
varchar
(
100
)
--
临时变量(查询条件过长时可能会出错,可修改100为1000)
declare
@strOrder
varchar
(
400
)
--
排序类型
if
@OrderType
!=
0
begin
set
@strTmp
=
'
<(select min
'
set
@strOrder
=
'
order by [
'
+
@fldName
+
'
] desc
'
end
else
begin
set
@strTmp
=
'
>(select max
'
set
@strOrder
=
'
order by [
'
+
@fldName
+
'
] asc
'
end
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
* from [
'
+
@tblName
+
'
] where [
'
+
@fldName
+
'
]
'
+
@strTmp
+
'
([
'
+
@fldName
+
'
]) from (select top
'
+
str
((
@PageIndex
-
1
)
*
@PageSize
)
+
'
[
'
+
@fldName
+
'
] from [
'
+
@tblName
+
'
]
'
+
@strOrder
+
'
) as tblTmp)
'
+
@strOrder
if
@strWhere
!=
''
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
* from [
'
+
@tblName
+
'
] where [
'
+
@fldName
+
'
]
'
+
@strTmp
+
'
([
'
+
@fldName
+
'
]) from (select top
'
+
str
((
@PageIndex
-
1
)
*
@PageSize
)
+
'
[
'
+
@fldName
+
'
] from [
'
+
@tblName
+
'
] where
'
+
@strWhere
+
'
'
+
@strOrder
+
'
) as tblTmp) and
'
+
@strWhere
+
'
'
+
@strOrder
if
@PageIndex
=
1
begin
set
@strTmp
=
''
if
@strWhere
!=
''
set
@strTmp
=
'
where
'
+
@strWhere
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
* from [
'
+
@tblName
+
'
]
'
+
@strTmp
+
'
'
+
@strOrder
end
if
@IsReCount
!=
0
set
@strSQL
=
'
select count(*) as Total from [
'
+
@tblName
+
'
]
'
+
'
where
'
+
@strWhere
exec
(
@strSQL
)
USE
[
Press
]
GO
/*
***** Object: StoredProcedure [dbo].[UP_GetRecordByPage] Script Date: 09/16/2012 00:26:26 *****
*/
SET
ANSI_NULLS
ON
GO
SET
QUOTED_IDENTIFIER
ON
GO
--
用途:支持任意排序的分页存储过程
CREATE
PROCEDURE
[
dbo
]
.
[
UP_GetRecordByPage
]
@tblName1
varchar
(
255
),
--
主表名 School
@tblName2
varchar
(
500
),
--
次表以及连接School left join City on School.CityID=City.ID left join County on School.CountyID=County.ID
@fldName
varchar
(
255
),
--
显示字段名
@OrderfldName
varchar
(
255
),
--
排序字段名,只能与一个排序字段名School.ID
@PageSize
int
=
10
,
--
页尺寸
@PageIndex
int
=
1
,
--
页码
@IsReCount
bit
=
1
,
--
返回记录总数, 非 0 值则返回
@OrderType
bit
=
0
,
--
设置排序类型, 非 0 值则降序
@strWhere
varchar
(
1000
)
=
''
,
--
查询条件 (注意: 不要加 where) 'School.SchoolName like ''%浙江%'''
@IsPrint
bit
=
0
--
是否打印
AS
declare
@strSQL
varchar
(
6000
)
--
主语句
declare
@strTmp
varchar
(
1000
)
--
临时变量(查询条件过长时可能会出错,可修改100为1000)
declare
@strOrder
varchar
(
400
)
--
排序类型
if
@OrderType
!=
0
begin
set
@strTmp
=
'
<(select min
'
set
@strOrder
=
'
order by
'
+
@OrderfldName
+
'
desc
'
end
else
begin
set
@strTmp
=
'
>(select max
'
set
@strOrder
=
'
order by
'
+
@OrderfldName
+
'
asc
'
end
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
'
+
@fldName
+
'
from
'
+
@tblName2
+
'
where
'
+
@OrderfldName
+
'
'
+
@strTmp
+
'
(
'
+
replace
(
@OrderfldName
,
@tblName1
,
'
tblTmp
'
)
+
'
) from (select top
'
+
str
((
@PageIndex
-
1
)
*
@PageSize
)
+
'
'
+
@OrderfldName
+
'
from
'
+
@tblName2
+
'
'
+
@strOrder
+
'
) as tblTmp)
'
+
@strOrder
if
@strWhere
!=
''
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
'
+
@fldName
+
'
from
'
+
@tblName2
+
'
where
'
+
@OrderfldName
+
'
'
+
@strTmp
+
'
(
'
+
replace
(
@OrderfldName
,
@tblName1
,
'
tblTmp
'
)
+
'
) from (select top
'
+
str
((
@PageIndex
-
1
)
*
@PageSize
)
+
'
'
+
@OrderfldName
+
'
from
'
+
@tblName2
+
'
where
'
+
@strWhere
+
'
'
+
@strOrder
+
'
) as tblTmp)
'
+
@strOrder
if
@PageIndex
=
1
begin
set
@strTmp
=
''
if
@strWhere
!=
''
set
@strTmp
=
'
where
'
+
@strWhere
set
@strSQL
=
'
select top
'
+
str
(
@PageSize
)
+
'
'
+
@fldName
+
'
from
'
+
@tblName2
+
'
'
+
@strTmp
+
'
'
+
@strOrder
end
if
@IsReCount
!=
0
set
@strSQL
=
@strSQL
+
'
/*----*/
'
+
'
select count(1) as Total from
'
+
@tblName2
+
'
'
if
@IsPrint
<>
0
print
(
@strSQL
)
exec
(
@strSQL
)
GO

