繁体   English   中英

如何避免“ where”子句影响行顺序?

[英]How to avoid a 'where' clause affecting row ordering?

我有一个从另一个select进行select的情况,如果添加where子句,则返回的行的顺序会更改。

例:

SELECT t.id
FROM (
       SELECT t.id
       FROM table1 t
       ORDER BY
         t.viewsTotal ASC
       LIMIT 20
       OFFSET 0
     ) base
  INNER JOIN table1 t ON base.id = t.id
  LEFT JOIN table2 t2 ON t2.id = t1.secondTableId
# WHERE t2.someBoolColumn = FALSE
;

现在,内部select和外部select的顺序相同,但是如果我取消注释where条件,则外部select将更改顺序。

如何防止这种情况发生?

对于给定的示例,假设以下内容:

  1. 我无法select
  2. 我不知道在执行外部select时对内部select应用了什么顺序。 因此,如果我从联接表订购,我将不知道需要在这里联接它。

有关我的用例的更多信息

有一个提供内部选择的查询构建器,它可以通过连接到该内部选择的第三个表来应用顺序,如果我想应用相同的顺序,则需要知道连接了哪些表,在这种情况下这个可怜的查询生成器的我不了解

tl; dr如果要在结果集中使用特定顺序,请使用ORDER BY

在没有ORDER BY子句的情况下,来自任何RDMS服务器的结果集中的行顺序在形式上是不可预测的。 不可预测的就像随机的,除了更糟。 随机排序意味着您每次运行查询时都会以不同的顺序获取行。 真正的随机排序(如果存在)会在您对排序的假设失败时使简单的单元测试难以通过。

不可预测的意味着您将以相同的顺序获得它们,直到您没有得到为止。 这意味着您的单元测试将通过,系统测试将通过,并且如果依赖结果集订购,则系统将在六个月内无法生产。

为什么会这样呢? 服务器的查询计划器可以随意使用任何算法来满足您提供的查询。 对于不同类型的表和不同大小的表,这些算法的工作方式不同。 如果您不通过指定结果集顺序来约束查询计划器,则它可能会选择某种算法,该算法给出的排序对程序员来说似乎很奇怪。

从字面上看,查询计划人员内置了数千年的程序员优化价值。

对于习惯于各种编程语言所鼓励的过程思维方式的人们,有时很难将您的思维切换到SQL使用的声明式/描述性模式。 使用SQL(至少是干净的SQL,没有诸如SELECT @a := @a+1和其他技巧之类的东西),您只是在描述所需的结果集。 服务器生成与您的规范匹配的结果。

我建议您不要依赖我的SQL生成的隐式排序(因为按照Bohemian的评论,没有隐式排序)。 而是,您应该使用ORDER BY语句,并在查询中选择要对结果进行排序的一列。 这样,无论WHERE子句如何,您都可以确保始终以相同的方式呈现结果。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM