当前位置: 首页 > 面试题库 >

PostgreSQL:ORDER BY和LIMIT / OFFSET发生奇怪的冲突

魏松
2023-03-14
问题内容

我正在尝试在PostgreSQL 9.1中做到这一点:

SELECT m.id, vm.id, vm.value
FROM m
LEFT JOIN vm ON vm.m_id = m.id and vm.variation_id = 1
ORDER BY lower(trim(vm.value)) COLLATE "C" ASC LIMIT 10 OFFSET 120

结果是:

 id |  id | value
----+-----+---------------
504 | 511 | "andr-223322"
506 | 513 | "andr-322223"
824 | 831 | "angHybrid"
866 | 873 | "Another thing"
493 | 500 | "App update required!"
837 | 844 | "App update required!"
471 | 478 | "April"
905 | 912 | "Are you sure you want to delete this thing?"
 25 |  29 | "Assignment"
196 | 201 | "AT ADDRESS"

好的,让我们使用以下命令执行相同的查询OFFSET 130

 id |  id | value
----+-----+---------------
196 | 201 | "AT ADDRESS"
256 | 261 | "Att Angle"
190 | 195 | "Att Angle"
273 | 278 | "Att Angle:"
830 | 837 | "attAngle"
475 | 482 | "August"
710 | 717 | "Averages"
411 | 416 | "AVG"
692 | 699 | "AVG SHAPE"
410 | 415 | "AVGs"

我们AT ADDRESS再次看到了我们的商品,但是一开始!!!

事实是该vm表包含以下两项:

 id | m_id | value
----+------+---------------
201 |  196 | "AT ADDRESS"
599 |  592 | "At Address"

我通过一种解决方法解决了这种情况:

(lower(trim(vm.value)) || vm.id)

但是什么地狱??? !!! 为什么必须使用替代方法?


问题答案:

宣誓就不会更改定义此行为的SQL标准。 除非在中指定,否则
行的顺序是 不确定的ORDER BY。每个文档:

如果未选择排序,则将以未指定的顺序返回行。在这种情况下,实际顺序将取决于扫描和联接计划的类型以及磁盘上的顺序,但不得依赖该顺序。只有明确选择了排序步骤,才能保证特定的输出顺序。

由于您没有为这两个同级定义顺序(按您的排序顺序):

 id | m_id | value
----+------+---------------
201 |  196 | "AT ADDRESS"
599 |  592 | "At Address"

..您可以随意订购-适用于Postgres的任何产品。带有的查询LIMIT通常使用不同的查询计划,该计划可以解释不同的结果。

使固定:

ORDER BY lower(trim(vm.value)) COLLATE "C" **, vm.id** ;

或者(可能更有意义-可能还会调整到现有索引):

ORDER BY lower(trim(vm.value)) COLLATE "C" **, vm.value, vm.id** ;

COLLATE "C"顺便说一句,这与在这里使用无关)。
不要 为此目的 而串联 ,这会更加昂贵,并且有可能无法使用 索引
(除非您在该精确表达式上具有索引)。添加另一个表达式,当ORDER BY列表中的先前表达式不明确时,该表达式将启动。

同样,由于您在 LEFT JOIN 那儿,所有m不匹配的行vm的所有当前ORDER BY表达式都为空值。它们排在最后,然后以其他方式任意排序。如果要总体上保持稳定的排序顺序,则也需要处理。喜欢:

ORDER BY lower(trim(vm.value)) COLLATE "C" **, vm.id, m.id** ;

阿西德斯

为什么要存储双引号?似乎是昂贵的噪音。没有他们,您可能会更好。如果需要,您总是可以在输出中添加引号。

许多客户端无法在一个结果中多次处理同一个列名。您需要为您的至少一个列别名id列:SELECT m.id AS m_id, vm.id AS vm_id ...。旨在说明为什么列的“ id”首先是反模式



 类似资料:
  • 问题内容: 我正在尝试使用SQL设置分页。我想要每页3个结果,这是我所做的: 我检查了很多次,这不是很复杂,但是我的结果并不是我所期望的: 第1页: 第2页 : 第3页: 第4页: 如您所见,第2、3和4页的结果相同…当我一次取4页时: 结果 : 也许我遗漏了一些东西或排序结果以及使用限制/偏移量不兼容,我不知道出了什么问题。 问题答案: 这里的问题是所有行的命中计数均为,因此使用时它们的位置是不

  • 问题内容: 我正在开发Java Web服务,当从IBM中型机(AS400)上的DB2数据库中获取大数据集时,允许分页。 例如; 如果数据集中有10000条记录,我想一次以1000个块的形式获取它们。 我发现这篇文章解释说我可以使用LIMIT和OFFSET。但是我需要将变量设置为。 现在,我一直在谷歌搜索,看到您可以使用来设置此变量。但是我无法找出在哪里键入此命令? 我正在Windows机器上进行开

  • 1. 定义 慕课解释: Limit用于对查询结果集数量进行限制;Offset 则常与 Limit 搭配,意为偏移,表示跳过一定数量的记录。 2. 前言 本小节,我们将一起学习 SQL 中的Limit和 Offset。 在实际的开发中,我们可能常常会遇到以下场景: 获得分数的前 5 名。 分页获取数据。 这些场景需要细粒度地控制数据库数据,因此 SQL 引入了 Limit 和 Offset 来帮助开

  • 问题内容: 在PostgreSQL中,有and关键字可以非常容易地分页结果集。 SQL Server的等效语法是什么? 问题答案: 相当于是,但如果你想通用分页,最好写这样的查询: 这样做的好处是,如果您决定更改分页选项(或允许用户这样做),则可以对偏移量和限制进行参数化。 注意:为此,该参数应使用基于1的索引,而不是基于零的常规索引。

  • 我正在考虑将我们传统的jpa/道解决方案迁移到Spring Data。 但是,我们的前端之一是SmartGWT,它们的数据库组件仅使用限制/偏移逐步加载数据,这使得难以使用Pagable。 这会导致问题,因为无法确定限制/偏移量最终是否可以转换为页码。(这可能因用户滚动方式、屏幕大小等而异)。 我查看了切片等,但无法找到在任何地方使用限制/偏移值的方法。 想知道有没有人有什么建议?最理想的情况是,

  • 问题内容: 我有一些限制数据以每页仅显示4个项目的代码。我使用的列大约有20到30个项目,因此我需要将这些项目分散在各个页面上。 在第一页上,我有: 您会在页面底部注意到我的定位标记,其中列出了第二个页面“ itempage2.php”。在项目页面2中,我具有相同的代码,除了我的select语句列出了偏移量4。 当我的数据库中有预定数量的项目时,这种方式可以运行。但这不是很好。仅当有更多项目时才需