![](/img/trans.png)
[英]How to use DISTINCT in WHERE CLAUSE to avoid repeated row returns
[英]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
将更改顺序。
如何防止这种情况发生?
对于给定的示例,假设以下内容:
select
。 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.