如何在过程中使用 ROW_NUMBER() 对数据进行分页
Posted
技术标签:
【中文标题】如何在过程中使用 ROW_NUMBER() 对数据进行分页【英文标题】:How to use ROW_NUMBER() for paging data in procedure 【发布时间】:2012-11-05 06:03:27 【问题描述】:我是 sql server 的初学者,我写了这个查询
ALTER PROCEDURE [dbo].[SPSelectReport3] (@StringWhereParameter nvarchar(4000)=null)
AS
BEGIN
SET NOCOUNT ON;
-- َ Begin Of Transaction
begin tran
declare @Query nvarchar(max)
set @Query='
((SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
FROM [MyMaterialDB].[dbo].[Report3]
WHERE headerid IN(SELECT HeaderId FROM [MyMaterialDB].[dbo].[Report3] WHERE line=''H'''+ @StringWhereParameter+'))
UNION
(
(SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
FROM [MyMaterialDB].[dbo].[Report3]
WHERE mesc IN(SELECT mesc FROM [MyMaterialDB].[dbo].[Report3] WHERE line=''I''' +@StringWhereParameter+'))
UNION
(SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
FROM [MyMaterialDB].[dbo].[Report3]
WHERE mesc IN(SELECT HeaderId FROM [MyMaterialDB].[dbo].[Report3] WHERE line=''I'''+@StringWhereParameter+')
)))
Order by Mesc,Line,unit'
exec(@Query)
if @@error = 0
Commit Tran
Else
rollback tran
End
我写了这个字符串 Query 和 Get Where 参数和 concat Query 以及之后运行 Query。我想要分页结果数据,但我不知道如何进行分页。请帮助我。谢谢大家。
【问题讨论】:
为什么你将参数作为字符串传递? @ Buzz : 在 Proc 中使用 asp.net 应用程序,在客户端创建动态位置并将其转换为字符串并发送到服务器。 我在这里没有得到你的意思,但是为了分页查看这些问题-***.com/questions/4358253/…; ***.com/questions/548475/… @Buzz:谢谢你的帮助。但是这个链接对我没有帮助。在这个查询中我有 3 个查询并将它联合起来,但我不知道如何在联合中分页查询 【参考方案1】:将整个事物(减去 ORDER BY)用作派生表并在外部查询中应用 ROW_NUMBER()(然后在最外部查询中按分配的行号进行过滤)应该没有问题。但我可能会先重写这个查询,可能是这样的:
'SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
FROM [MyMaterialDB].[dbo].[Report3] t
WHERE EXISTS (
SELECT *
FROM [MyMaterialDB].[dbo].[Report3]
WHERE (Line = ''H'' AND HeaderId = t.HeaderId
OR Line = ''I'' AND t.Mesc IN (Mesc, HeaderId)
) ' + @StringWhereParameter + '
)'
现在添加行号列应该很容易了:
'SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
,ROW_NUMBER() OVER (ORDER BY Mesc, Line, Unit) AS rn
FROM [MyMaterialDB].[dbo].[Report3] t
WHERE EXISTS (
SELECT *
FROM [MyMaterialDB].[dbo].[Report3]
WHERE (Line = ''H'' AND HeaderId = t.HeaderId
OR Line = ''I'' AND t.Mesc IN (Mesc, HeaderId)
) ' + @StringWhereParameter + '
)'
然后对其进行过滤
'SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
FROM (
SELECT Id,[Mesc]
,[Line]
,[Unit]
,[Discription]
,[InvQty]
,[LastDateNil]
,[ST_CODE]
,[PlanCode]
,[Min]
,[Max]
,[PbsNo]
,[PbsDate]
,[PbsQty]
,[PbsQtyRec]
,[DateDelay]
,[PartNo]
,[TranQty]
,[TypeRequest]
,[HeaderId]
,ROW_NUMBER() OVER (ORDER BY Mesc, Line, Unit) AS rn
FROM [MyMaterialDB].[dbo].[Report3] t
WHERE EXISTS (
SELECT *
FROM [MyMaterialDB].[dbo].[Report3]
WHERE (Line = ''H'' AND HeaderId = t.HeaderId
OR Line = ''I'' AND t.Mesc IN (Mesc, HeaderId)
) ' + @StringWhereParameter + '
)
) s
WHERE rn BETWEEN @offset + 1 AND @offset + @pagesize
;'
【讨论】:
以上是关于如何在过程中使用 ROW_NUMBER() 对数据进行分页的主要内容,如果未能解决你的问题,请参考以下文章
在 SQL Server 2005 中使用 ROW_NUMBER() OVER () 对不同列进行排序的分页查询
关于Oracle row_number() over()的简单使用
如何在 Room @Query 中使用 ROW_NUMBER()?
clickhouse实践clickhouse中如何实现ROW_NUMBER() OVER(PARTITION BY ‘xxx‘ ORDER BY ‘xxx‘ DESC/ASC)
clickhouse实践clickhouse中如何实现ROW_NUMBER() OVER(PARTITION BY ‘xxx‘ ORDER BY ‘xxx‘ DESC/ASC)