如何使用键集分页?
How to use keyset pagination?
假设我在数据库中总共有 800 行符合条件的行,这些行按列 requisitionid
降序排列。我想在 80 页中显示记录,每页有 10 行。我们使用 requisitionid
作为搜索谓词。那么谓词应该小于还是大于?由于查询将从 UI (Angular + primeNG) 开始,我只想发送一个参数 - requisitionid
。如果小于查询,则查询为SELECT ... FROM ... where requisitionid < ?
,所以这里我们说的是第一行。如果我们使用大于查询,即 SELECT ... FROM ... where requisitionid > ?
,这里我们讨论的是页面的最后一行。
编辑
实际代码:
with topten as (SELECT DISTINCT TOP 10
REQN.CASE_ID
,userContact2.BV_First_Name + ' ' + userContact2.BV_Last_Name ReQCreater
,REQN.BV_Internal_Job_Title
,REQN.BV_Posted_Job_Title as postedJobTitle
,REQN.BV_Status
,REQN.BV_Taleo_Id
,REQN.BV_WD_PositionID
,jobcode.BV_Job_Code
,loc.BV_LocationCode
,loc.BV_LocationName
,D.BV_Division_Code AS 'divCode',
ISNULL(loc.BV_Address1,'') + CASE WHEN ISNULL(loc.BV_Address1,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_Address2,'') + CASE WHEN ISNULL(loc.BV_Address2,'') = '' THEN '' ELSE ', ' END
+ ISNULL(loc.BV_City,'') + CASE WHEN ISNULL(loc.BV_City,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_State,'') + CASE WHEN ISNULL(loc.BV_State,'') = '' THEN '' ELSE (case when ISNULL(loc.BV_ZipCode,'') = '' THEN '' ELSE ', ' END) END
+ ISNULL(loc.BV_ZipCode,'') AS locationAddress
from dbo.CW_V_REQN as REQN
INNER JOIN dbo.CW_TL_Requisition__Location_Master as reqLocLink on REQN.CASE_ID = reqLocLink.FROM_ID
INNER JOIN dbo.CW_V_LOCTMAST as loc on loc.CASE_ID = reqLocLink.TO_ID
INNER JOIN dbo.CW_TL_UserContactInfo__Location_Master as locUserLink on locUserLink.TO_ID = loc.CASE_ID
INNER JOIN dbo.CW_V_USERCONT as userContact on userContact.CASE_ID = locUserLink.FROM_ID
LEFT JOIN dbo.CW_TL_Requisition__Department as reqDeptLink on REQN.CASE_ID = reqDeptLink.FROM_ID
INNER JOIN dbo.CW_V_DEPARTME as dept on dept.CASE_ID = reqDeptLink.TO_ID
LEFT JOIN dbo.CW_TL_UserContactInfo__Department_Master as deptUserLink on dept.CASE_ID=deptUserLink.TO_ID
INNER JOIN dbo.CW_TL_Requisition__Job_Code as reqJobLink on REQN.CASE_ID = reqJobLink.FROM_ID
LEFT JOIN dbo.CW_V_JOBCODE as jobcode on jobcode.CASE_ID = reqJobLink.TO_ID
LEFT JOIN dbo.CW_V_USERCONT as userContact2 on (userContact2.BV_Login_Name = REQN.CREATED_BY)
LEFT JOIN CW_TL_LocationMaster__Division_Master LD ON (LD.FROM_ID = loc.CASE_ID)
LEFT JOIN CW_V_DIVISION D ON (D.CASE_ID = LD.TO_ID)
WHERE userContact.BV_Login_Name = @LOGINNAME
AND REQN.CASE_ID < @MINCASEIDPREVPAGE
ORDER BY REQN.CASE_ID DESC
)
select 名列前茅。*
, T.*
来自 topten
cross join (select min(case_id) as min from topten) as T
如果我理解您的问题,您应该能够在 SELECT
查询末尾使用以下子句:
OFFSET (@Page * 10) ROWS FETCH NEXT 10 ROWS ONLY
如果这不是您要查找的内容,请post您当前的查询,以便我们了解您现在正在做什么。
对于降序键的基于键的分页,WHERE 子句谓词对于下一页应该是 <
,对于上一页应该是 >
。此外,前一页的 ORDER BY
子句需要 ASC
(对于 TOP 谓词)以及外部 DESC
(对于降序键显示序列)。下面是一个例子。
--create test table with sample data
CREATE TABLE dbo.YourTable(
requisitionid int PRIMARY KEY
);
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1000 AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
INSERT INTO dbo.YourTable WITH(TABLOCKX)
SELECT num
FROM t1000
WHERE num <= 800;
GO
--query for first page (page 1) on descending key (returns 800-791)
SELECT TOP(10) requisitionid
FROM YourTable
ORDER BY requisitionid DESC;
GO
--query for next page (page 2) on descending key (returns 790-781)
DECLARE @LastRequisitionIdOnPage int = 791;
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid < @LastRequisitionIdOnPage
ORDER BY requisitionid DESC;
GO
--query for previous page (page 1) on descending key (returns 800-791)
DECLARE @FirstRequisitionIdOnPage int = 790;
SELECT requisitionid
FROM (
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid > @FirstRequisitionIdOnPage
ORDER BY requisitionid ASC
) AS prev_page
ORDER BY requisitionid DESC;;
GO
假设我在数据库中总共有 800 行符合条件的行,这些行按列 requisitionid
降序排列。我想在 80 页中显示记录,每页有 10 行。我们使用 requisitionid
作为搜索谓词。那么谓词应该小于还是大于?由于查询将从 UI (Angular + primeNG) 开始,我只想发送一个参数 - requisitionid
。如果小于查询,则查询为SELECT ... FROM ... where requisitionid < ?
,所以这里我们说的是第一行。如果我们使用大于查询,即 SELECT ... FROM ... where requisitionid > ?
,这里我们讨论的是页面的最后一行。
编辑 实际代码:
with topten as (SELECT DISTINCT TOP 10
REQN.CASE_ID
,userContact2.BV_First_Name + ' ' + userContact2.BV_Last_Name ReQCreater
,REQN.BV_Internal_Job_Title
,REQN.BV_Posted_Job_Title as postedJobTitle
,REQN.BV_Status
,REQN.BV_Taleo_Id
,REQN.BV_WD_PositionID
,jobcode.BV_Job_Code
,loc.BV_LocationCode
,loc.BV_LocationName
,D.BV_Division_Code AS 'divCode',
ISNULL(loc.BV_Address1,'') + CASE WHEN ISNULL(loc.BV_Address1,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_Address2,'') + CASE WHEN ISNULL(loc.BV_Address2,'') = '' THEN '' ELSE ', ' END
+ ISNULL(loc.BV_City,'') + CASE WHEN ISNULL(loc.BV_City,'') = '' THEN '' ELSE ', ' END + ISNULL(loc.BV_State,'') + CASE WHEN ISNULL(loc.BV_State,'') = '' THEN '' ELSE (case when ISNULL(loc.BV_ZipCode,'') = '' THEN '' ELSE ', ' END) END
+ ISNULL(loc.BV_ZipCode,'') AS locationAddress
from dbo.CW_V_REQN as REQN
INNER JOIN dbo.CW_TL_Requisition__Location_Master as reqLocLink on REQN.CASE_ID = reqLocLink.FROM_ID
INNER JOIN dbo.CW_V_LOCTMAST as loc on loc.CASE_ID = reqLocLink.TO_ID
INNER JOIN dbo.CW_TL_UserContactInfo__Location_Master as locUserLink on locUserLink.TO_ID = loc.CASE_ID
INNER JOIN dbo.CW_V_USERCONT as userContact on userContact.CASE_ID = locUserLink.FROM_ID
LEFT JOIN dbo.CW_TL_Requisition__Department as reqDeptLink on REQN.CASE_ID = reqDeptLink.FROM_ID
INNER JOIN dbo.CW_V_DEPARTME as dept on dept.CASE_ID = reqDeptLink.TO_ID
LEFT JOIN dbo.CW_TL_UserContactInfo__Department_Master as deptUserLink on dept.CASE_ID=deptUserLink.TO_ID
INNER JOIN dbo.CW_TL_Requisition__Job_Code as reqJobLink on REQN.CASE_ID = reqJobLink.FROM_ID
LEFT JOIN dbo.CW_V_JOBCODE as jobcode on jobcode.CASE_ID = reqJobLink.TO_ID
LEFT JOIN dbo.CW_V_USERCONT as userContact2 on (userContact2.BV_Login_Name = REQN.CREATED_BY)
LEFT JOIN CW_TL_LocationMaster__Division_Master LD ON (LD.FROM_ID = loc.CASE_ID)
LEFT JOIN CW_V_DIVISION D ON (D.CASE_ID = LD.TO_ID)
WHERE userContact.BV_Login_Name = @LOGINNAME
AND REQN.CASE_ID < @MINCASEIDPREVPAGE
ORDER BY REQN.CASE_ID DESC
)
select 名列前茅。* , T.* 来自 topten cross join (select min(case_id) as min from topten) as T
如果我理解您的问题,您应该能够在 SELECT
查询末尾使用以下子句:
OFFSET (@Page * 10) ROWS FETCH NEXT 10 ROWS ONLY
如果这不是您要查找的内容,请post您当前的查询,以便我们了解您现在正在做什么。
对于降序键的基于键的分页,WHERE 子句谓词对于下一页应该是 <
,对于上一页应该是 >
。此外,前一页的 ORDER BY
子句需要 ASC
(对于 TOP 谓词)以及外部 DESC
(对于降序键显示序列)。下面是一个例子。
--create test table with sample data
CREATE TABLE dbo.YourTable(
requisitionid int PRIMARY KEY
);
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t1000 AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num FROM t10 AS a CROSS JOIN t10 AS b CROSS JOIN t10 AS c)
INSERT INTO dbo.YourTable WITH(TABLOCKX)
SELECT num
FROM t1000
WHERE num <= 800;
GO
--query for first page (page 1) on descending key (returns 800-791)
SELECT TOP(10) requisitionid
FROM YourTable
ORDER BY requisitionid DESC;
GO
--query for next page (page 2) on descending key (returns 790-781)
DECLARE @LastRequisitionIdOnPage int = 791;
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid < @LastRequisitionIdOnPage
ORDER BY requisitionid DESC;
GO
--query for previous page (page 1) on descending key (returns 800-791)
DECLARE @FirstRequisitionIdOnPage int = 790;
SELECT requisitionid
FROM (
SELECT TOP(10) requisitionid
FROM YourTable
WHERE requisitionid > @FirstRequisitionIdOnPage
ORDER BY requisitionid ASC
) AS prev_page
ORDER BY requisitionid DESC;;
GO