查询偏移量 returns 重叠的数据集
Query with offset returns overlapping data sets
最初尝试获得非常简单的分页,使用获取 n 行然后使用偏移量进行后续调用,在 Oracle 中给出了重叠的条目。
我期待以下内容能给我两组独特的结果。如果将第一行的限制设置为 200,将返回结果的 1-100,然后是 101-200。
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" fetch first 100 rows only ;
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" offset 100 rows fetch next 100 rows only ;
所以如果批准人 A 有 150 个项目,第一个结果应该是:
- A, item1
- .....
- A, item100
后续调用(偏移 100)给出
- A, item101
- ...
- A, item150
- B, item1
- B, item2
- .....
- B, item201
不幸的是,第二组包含第一批值中的一些条目。可能是一个非常愚蠢的错误,但我找不到关于为什么会发生这种情况的解释。
---- 根据评论更新
主键由 Approver 和其他几个字段组成,它们共同构成一个复合且唯一的主键。
代码将通过 ODBC 调用,并将用于 Oracle 和 MySQL 后端。
在 Oracle 中,如果您对包含相同值的列进行“排序依据”(就像您有 - 'A'、'A'、'A' ...)的顺序'A' 值内的记录将是随机的。
请尝试将您的查询更改为... order by "APPROVER", rowid
...
据推测,APPROVER
不是唯一列。由于可能存在重复,order by
子句不稳定,offset子句可能会产生重复。
一个简单的解决方案是在 order by
中添加更多列以打破平局。假设 (approver, item)
是一组唯一的列,那就是:
select *
from appr
where approver = 'A' or approver > 'A'
order by approver, item
fetch first 100 rows only
-- then: offset 100 rows fetch next 100 rows only
备注:
不需要用双引号将 all-caps 标识符(表名或列名)括起来:这是 Oracle 中的默认设置
or
条件周围的括号在这种简单情况下是多余的
如果approver
总是一个字符长,那么where
子句可以简化为where approver >= 'A'
只有当你真的知道你为什么这样做时才使用索引提示(我不是说你不知道,但我删除了它,以防万一);大多数时候,数据库知道得更多
最初尝试获得非常简单的分页,使用获取 n 行然后使用偏移量进行后续调用,在 Oracle 中给出了重叠的条目。
我期待以下内容能给我两组独特的结果。如果将第一行的限制设置为 200,将返回结果的 1-100,然后是 101-200。
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" fetch first 100 rows only ;
select * from "APPR" /*+ index(APPR APPR_IDX01) */ where ("APPROVER" = 'A') or ("APPROVER" > 'A') order by "APPROVER" offset 100 rows fetch next 100 rows only ;
所以如果批准人 A 有 150 个项目,第一个结果应该是:
- A, item1
- .....
- A, item100
后续调用(偏移 100)给出
- A, item101
- ...
- A, item150
- B, item1
- B, item2
- .....
- B, item201
不幸的是,第二组包含第一批值中的一些条目。可能是一个非常愚蠢的错误,但我找不到关于为什么会发生这种情况的解释。
---- 根据评论更新 主键由 Approver 和其他几个字段组成,它们共同构成一个复合且唯一的主键。
代码将通过 ODBC 调用,并将用于 Oracle 和 MySQL 后端。
在 Oracle 中,如果您对包含相同值的列进行“排序依据”(就像您有 - 'A'、'A'、'A' ...)的顺序'A' 值内的记录将是随机的。
请尝试将您的查询更改为... order by "APPROVER", rowid
...
据推测,APPROVER
不是唯一列。由于可能存在重复,order by
子句不稳定,offset子句可能会产生重复。
一个简单的解决方案是在 order by
中添加更多列以打破平局。假设 (approver, item)
是一组唯一的列,那就是:
select *
from appr
where approver = 'A' or approver > 'A'
order by approver, item
fetch first 100 rows only
-- then: offset 100 rows fetch next 100 rows only
备注:
不需要用双引号将 all-caps 标识符(表名或列名)括起来:这是 Oracle 中的默认设置
or
条件周围的括号在这种简单情况下是多余的如果
approver
总是一个字符长,那么where
子句可以简化为where approver >= 'A'
只有当你真的知道你为什么这样做时才使用索引提示(我不是说你不知道,但我删除了它,以防万一);大多数时候,数据库知道得更多