如何在过程中使用 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)

如何在 MySQL 中使用 ROW_NUMBER 来检查每位员工每天的行数?