MS SQL 分页和分组
MS SQL pagination and grouping
我需要帮助,因为我正在为如何翻页和限制每一页一次只显示一个进程而苦苦挣扎。我尝试了很多东西,我的大脑被炸了。帮助........
因此,如果 @PageNum = 1 and @Pagesize = 10
并且第一个进程有 7 行;第一页将显示第一个进程的 7 行(正是我想要的)。
现在,如果用户选择 @PageNum = 2 and @Pagesize is 10
并且第二个进程有 11 个。我希望它显示下一个进程的前 10 个。
目前只显示第二个进程的最后 8 个。
我简化了 SQL 以删除业务信息,然后只显示我正在处理的列表:
/*
notes:
Parameters passed in are @PageNum and @PageSize
@PageNum is which page they user goes to
@PageSize is the max number of rows to show
*/
DECLARE @StartRow int, @EndRow int
SET @StartRow = (@PageNum -1) * @PageSize +1;
SET @EndRow = @PageNum * @PageSize;
WITH ProcessestoPageThru AS
(Select Name,
ProcessId,
ROW_NUMBER() OVER(ORDER BY Name, ProcessId, ) as RowNo,
COUNT(Name) OVER() as RowCnt
from a whole bunch of tables
where a whole bunch of criteria
)
SELECT * INTO #tmp_ProcessestoPageThru
From ProcessestoPageThru
Where RowNo BETWEEN @StartRow AND @EndRow
Declare @ProcessID int
--Get the top ProcessID, We are only going to display one Process at a time
Select Top 1 @ProcessID = ProcessId
From #tmp_ProcessestoPageThru
Select *
from #tmp_ProcessestoPageThru
Where ProcessId = @ProcessId
请参阅附件示例:
Example
您还需要在 ProcessId
上执行 PARTITION BY
以按该列值显示结果。这是可以帮助您做到这一点的代码。
;WITH ProcessestoPageThru AS
(
Select Name,
ProcessId,
ROW_NUMBER() OVER( PARTITION BY ProcessId ORDER BY Name, ProcessId ) as RowNo,
COUNT(Name) OVER() as RowCnt
FROM processes
)
SELECT Name,
ProcessId,
RowNo,
RowCnt
From ProcessestoPageThru
Where RowNo BETWEEN @StartRow AND @EndRow
AND ProcessId = @ProcessID
尝试使用其他示例数据。
如果实际数据速度慢,请告诉我详细信息。
i) 除了其他搜索条件之外,您只传递@Pageinde、@Pagesize 等参数。
ii)TotalPage 是您获得的页面数,并且必须 ppolate 您的页面 accirdingly.forget 旧计算。
iii) 不需要 rowcnt。
declare @Pageindex int=1
declare @Pagesize int=10
declare @t table(processid int, rowcnt int)
insert into @t values(1,345),(1,345),(1,345),(1,345),(1,345),(1,345),(1,345)
,(1,345),(1,345),(1,345),(1,345),(1,345)
,(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345)
,(2,345),(2,345),(2,345),(3,345),(3,345)
;with CTE as
(
select *
,DENSE_RANK()over(order by processid) rownum
--,ROW_NUMBER()over(partition by processid order by processid) rownum1
,ROW_NUMBER()over(order by processid) rownum2
from @t
)
,CTE1 AS(
select *,
case when (rownum2/cast(@Pagesize as FLOAT))=1 then (rownum2/@Pagesize )
ELSE (rownum2/@Pagesize )+rownum END PageIndex
from cte c
)
select processid,rownum2
,(select max(PageIndex) from cte1) TotalPage
from cte1
where PageIndex=@Pageindex
我需要帮助,因为我正在为如何翻页和限制每一页一次只显示一个进程而苦苦挣扎。我尝试了很多东西,我的大脑被炸了。帮助........
因此,如果 @PageNum = 1 and @Pagesize = 10
并且第一个进程有 7 行;第一页将显示第一个进程的 7 行(正是我想要的)。
现在,如果用户选择 @PageNum = 2 and @Pagesize is 10
并且第二个进程有 11 个。我希望它显示下一个进程的前 10 个。
目前只显示第二个进程的最后 8 个。
我简化了 SQL 以删除业务信息,然后只显示我正在处理的列表:
/*
notes:
Parameters passed in are @PageNum and @PageSize
@PageNum is which page they user goes to
@PageSize is the max number of rows to show
*/
DECLARE @StartRow int, @EndRow int
SET @StartRow = (@PageNum -1) * @PageSize +1;
SET @EndRow = @PageNum * @PageSize;
WITH ProcessestoPageThru AS
(Select Name,
ProcessId,
ROW_NUMBER() OVER(ORDER BY Name, ProcessId, ) as RowNo,
COUNT(Name) OVER() as RowCnt
from a whole bunch of tables
where a whole bunch of criteria
)
SELECT * INTO #tmp_ProcessestoPageThru
From ProcessestoPageThru
Where RowNo BETWEEN @StartRow AND @EndRow
Declare @ProcessID int
--Get the top ProcessID, We are only going to display one Process at a time
Select Top 1 @ProcessID = ProcessId
From #tmp_ProcessestoPageThru
Select *
from #tmp_ProcessestoPageThru
Where ProcessId = @ProcessId
请参阅附件示例:
Example
您还需要在 ProcessId
上执行 PARTITION BY
以按该列值显示结果。这是可以帮助您做到这一点的代码。
;WITH ProcessestoPageThru AS
(
Select Name,
ProcessId,
ROW_NUMBER() OVER( PARTITION BY ProcessId ORDER BY Name, ProcessId ) as RowNo,
COUNT(Name) OVER() as RowCnt
FROM processes
)
SELECT Name,
ProcessId,
RowNo,
RowCnt
From ProcessestoPageThru
Where RowNo BETWEEN @StartRow AND @EndRow
AND ProcessId = @ProcessID
尝试使用其他示例数据。
如果实际数据速度慢,请告诉我详细信息。
i) 除了其他搜索条件之外,您只传递@Pageinde、@Pagesize 等参数。
ii)TotalPage 是您获得的页面数,并且必须 ppolate 您的页面 accirdingly.forget 旧计算。
iii) 不需要 rowcnt。
declare @Pageindex int=1
declare @Pagesize int=10
declare @t table(processid int, rowcnt int)
insert into @t values(1,345),(1,345),(1,345),(1,345),(1,345),(1,345),(1,345)
,(1,345),(1,345),(1,345),(1,345),(1,345)
,(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345),(2,345)
,(2,345),(2,345),(2,345),(3,345),(3,345)
;with CTE as
(
select *
,DENSE_RANK()over(order by processid) rownum
--,ROW_NUMBER()over(partition by processid order by processid) rownum1
,ROW_NUMBER()over(order by processid) rownum2
from @t
)
,CTE1 AS(
select *,
case when (rownum2/cast(@Pagesize as FLOAT))=1 then (rownum2/@Pagesize )
ELSE (rownum2/@Pagesize )+rownum END PageIndex
from cte c
)
select processid,rownum2
,(select max(PageIndex) from cte1) TotalPage
from cte1
where PageIndex=@Pageindex