从 SQL Server 中的两个表进行分页

问题描述 投票:0回答:1

我有两个具有以下架构的表:

  • Table A
    ColumnA, UserId,
    ... - 为了简洁,省略了架构的其余部分
  • Table B
    ColumnB, UserId,
    ... - 为了简洁,省略了架构的其余部分

表之间可以有重复的值。例如 - 表 A 行

(<some-columnA-value>, 1, ...)
和表 B 行
(<some-columnB-value>, 1, ...)
,1 是 UserId。

现在,我有一个 API,用于从两个表中获取所有

UserId
值。随着数据的增加,我现在想为此 API 使用分页,并希望相应地修改查询。页面之间或页面内也不应该有任何重复项。

我如何实现这一目标?还有一个要求是我需要使用键集分页而不是偏移分页,因为当偏移量增加时,偏移分页会变得更慢。

到目前为止,我已经考虑过使用索引视图,因为我只需要获取 1 列,但由于数据不断频繁且大量地变化,维护索引视图的开销并不是最佳的。

表A:

A 栏 用户ID
x 1
y 2
z 3
w 4

表B:

B 栏 用户ID
a 1
b 3
c 5
d 6

结果(如果没有页面尺寸):

用户ID
1
2
3
4
5
6

结果(如果页面大小为 3)

第 1 页

用户ID
1
2
3

第2页

用户ID
4
5
6
sql-server t-sql indexing pagination
1个回答
0
投票

正如我在我关于 Keyset Pagination(按键分页)的规范帖子中提到的,基本查询需要高效。

您的情况的关键(原文如此)是使用合并并,然后在过滤到前 3 个之后对该集合进行区分。

所以首先

UNION ALL

将表格放在一起,然后取前3名(包括平局),然后
DISTINCT
最终结果。

WITH Unioned AS ( SELECT a.UserId FROM TableA a UNION ALL SELECT b.UserId FROM TableB b ), Topped AS ( SELECT TOP (3) WITH TIES t.UserId FROM Unioned t ORDER BY UserId ) SELECT DISTINCT t.UserId FROM Topped t;
最终的查询计划漂亮整洁。

正如我提到的,您需要保留之前的最高 ID 值,并将其传递给下一个查询。将其放在

TOP

 部分,编译器通常会将其下推到较低级别。如果您愿意,您可以将其放入联盟的两半中。

WITH Unioned AS ( SELECT a.UserId FROM TableA a UNION ALL SELECT b.UserId FROM TableB b ), Topped AS ( SELECT TOP (3) WITH TIES t.UserId FROM Unioned t WHERE t.UserId = @previousId ORDER BY UserId ) SELECT DISTINCT t.UserId FROM Topped t;

db<>小提琴

© www.soinside.com 2019 - 2024. All rights reserved.