SQL Where 子句顺序

Posted

技术标签:

【中文标题】SQL Where 子句顺序【英文标题】:SQL Where clause order 【发布时间】:2022-01-20 06:33:45 【问题描述】:

我有这个 SQL 查询:

SELECT 
    Runs.runID, Runs.runDateTime,
    COUNT(Files.destFileID) AS FileCount
FROM
    Runs
LEFT OUTER JOIN 
    Files ON Files.runID = Runs.runID
WHERE 
    FileCount > 0
GROUP BY 
    Runs.runID, Runs.runDateTime
ORDER BY 
    Runs.runDateTime

它运行良好并在没有WHERE 行的情况下显示预期结果,但我确实需要过滤结果数据,因为这意味着。

我得到的错误是

列名“FileCount”无效

WHERE 关键字之后。

我一直在阅读,但在网上找不到任何包含我拥有的所有元素的资源。

【问题讨论】:

这是最高结果from a Google search SQL 语句不会从上到下解释。顺序是 FROM、WHERE、GROUP、HAVING、SELECT、ORDER(没有穷举,例如窗口函数在 where 和 group 之间完成)。您不能在序列的早期部分中使用序列后期的某些内容 (HAVING 是应用于 GROUP BY 的 WHERE) 【参考方案1】:

您不能通过 WHERE 中的别名引用列,您需要在 WHERE 中重复表达式。然而,由于你的表达式是一个聚合,你实际上需要把它放在HAVING

SELECT R.runID,
       R.runDateTime,
       COUNT(F.destFileID) AS FileCount
FROM dbo.Runs R
     LEFT OUTER JOIN dbo.Files ON F.runID = R.runID
GROUP BY R.runID,
         R.runDateTime
HAVING COUNT(F.destFileID) > 0
ORDER BY R.runDateTime;

详细说明为什么您不能在 WHERE(或此处为 HAVING)中通过别名引用该列,这是由于 Logical Processing Order of the SELECT statement,这表明 WHERE 已处理第 4 部分,和HAVING 7th,但是,SELECT 是第8个处理部分。由于在处理WHERE 时尚未处理SELECT,因此无法引用其中定义的内容[SELECT]。在编程意义上,这就像在定义变量之前尝试引用它。

根据文档,操作顺序如下(请注意并非总是如此,但之前链接的文档对此进行了更详细的介绍):

    来自 开启 加入 在哪里 分组依据 使用多维数据集或使用汇总 有 选择 不同 订购人 顶部

【讨论】:

是的,那些文档坏了。它缺少APPLYOFFSET 和窗口函数,而ONJOIN 是同一件事(除非它指的是嵌套连接,它也缺少), @Charlieface 您可以随时提出问题或为文档发送 PR;它们是开源的。在这里说他们“坏了”并没有任何意义。【参考方案2】:

谢谢拉努,我会在 10 分钟后接受你的回答,但是在发布我的问题后,我发现我可以对整个事情进行子查询:

SELECT *
FROM (
    SELECT Runs.runID ,Runs.runDateTime ,COUNT(Files.destFileID) AS FileCount
    FROM Runs
    LEFT OUTER JOIN Files ON Files.runID = Runs.runID
    WHERE FileCount > 0
    GROUP BY Runs.runID, Runs.runDateTime
    ORDER BY Runs.runDateTime
)
AS results
  WHERE FileCount > 0
  ORDER BY runDateTime

这也有效。有谁知道这些选项中的哪些是最佳做法,或者每个选项的性能?

【讨论】:

这似乎是一个新问题,基于最后你问哪个是更好的做法或执行者。尽管您可以检查查询计划并查看它们的运行方式是否不同(我怀疑不是)。 我本来是想给出答案的,但是 larnu 的答案在 Sql 方面是更快更有效的方式。影响会在更大的数据时显示出来。 这个性能(和查询计划)将完全相同,虽然我注意到你不能在派生表中有ORDER BY(你也不需要它) 我会使用 HAVING,因为它更整洁

以上是关于SQL Where 子句顺序的主要内容,如果未能解决你的问题,请参考以下文章

sql where子句中的列顺序

在SQL语句中同时包含where子句,groupby子句,having子句及聚集函数,将按照怎么样的顺序执行?

WHERE 谓词的顺序和 SQL 优化器

按查询的where子句中的字段顺序对sql查询的结果进行排序

sql优化

Oracle初级优化sql