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)
但是什么地狱??? !!!
为什么我必须使用解决方法?
解决方法
除非在ORDER BY中指定,否则行的顺序是未定义的. Per documentation:
If sorting is not chosen,the rows will be returned in an unspecified
order. The actual order in that case will depend on the scan and join
plan types and the order on disk,but it must not be relied on. A
particular output ordering can only be guaranteed if the sort step is explicitly chosen.
由于您没有为这两个对等方定义订单(按您的排序顺序):
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,因此在mm中没有匹配的m中的行对于所有当前ORDER BY表达式都具有空值.它们是最后的,并且是任意排序的.如果你想要一个稳定的排序顺序,你也需要处理它.喜欢:
ORDER BY lower(trim(vm.value)) COLLATE "C",m.id;
旁白
为什么要存储双引号?似乎是昂贵的噪音.没有它们你可能会更好.如果需要,您始终可以在输出中添加引号.
许多客户端无法在一个结果中多次处理相同的列名称.您需要至少一个id列的列别名:SELECT m.id AS m_id,vm.id AS vm_id ….去显示为什么列的“id”是一个反模式开始.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。