百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

SQL查询是从Select开始的吗?(sql的select查询语句的顺序)

toyiye 2024-07-16 05:38 9 浏览 0 评论

作者 | Julia Evans
译者 | 王雪迎 责编 | 孙胜
出品 | CSDN(ID:CSDNnews)

好吧,显然很多SQL查询都是从SELECT开始的(实际上本文只是关注SELECT查询,而不是INSERT或其它别的什么)。

但是!昨天我正在做窗口函数的解释说明,并且我发现自己在谷歌上搜索“你能根据窗口函数的结果进行过滤吗”。比如 — 你能在WHERE、HAVING或者其它地方过滤窗口函数的结果吗?

最后我得出的结论是:“窗口函数必须在WHERE和GROUP BY之后运行,所以你做不到”。但这让我想到了一个更大的问题 — SQL查询的实际运行顺序是什么?

这是我凭直觉就知道的事情(“我肯定知道!我已经编写了至少10000个SQL查询,其中一些非常复杂!),但我很难真正地准确说出顺序是什么。


SQL查询按此顺序进行


这就是我查找到的顺序!(SELECT并不是在第一步执行,而是到第五步才执行)

这里是一篇推特 https://twitter.com/b0rk/status/1179449535938076673

(我真的很想找到一种比“sql查询按此顺序发生/运行”更准确的表达方式,但我还没想出来。)


在非图形格式中,其顺序为:

l FROM/JOIN 和所有的 ON 条件l WHEREl GROUP BYl HAVINGl SELECT(包括窗口函数)l ORDER BYl LIMIT


图解此图有助于你做出回答


此图是关于SQL查询的语义的 — 你可以通过它,对给定查询将返回什么结果进行推理,并回答如下问题:

  • 我能在一个GROUP BY的结果上执行WHERE么?(不行!WHERE发生在GROUP BY之前!)

  • 我可以根据窗口函数的结果进行过滤吗(不行!窗口函数发生在SELECT中,它发生在WHERE和GROUP BY之后)

  • 我可以基于GROUP BY中所做的来进行ORDER BY么?(可以!ORDER BY是最后执行的基本步骤,你可以根据任何东西做ORDER BY!)

  • LIMIT何时执行?(在最后!)

数据库引擎实际并不是按这个顺序运行查询


因为它实现了一系列优化以使查询运行得更快 — 我们稍后将在本文中讨论这一点。

所以:

  • 当你只想了解哪些查询是有效的,以及如何推理给定查询的结果时,可以使用此图。

  • 你不应该使用此图来解释查询性能或任何有关索引的事情,那是一个复杂得多的问题,涉及更多变量。

混淆因素:列别名


有人在Twitter上指出,许多SQL实现允许你使用以下语法:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)FROM tableGROUP BY full_name

此查询使其看起来像是在SELECT之后才发生GROUP BY,即使GROUP BY先执行,因为GROUP BY引用了SELECT中的别名。但是要使GROUP BY发挥作用,其实并不需要在SELECT之后才运行 — 数据库引擎只要将查询重写为:

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)FROM tableGROUP BY CONCAT(first_name, ' ', last_name)

并且首先运行GROUP BY。

你的数据库引擎肯定还会在开始运行查询之前执行一系列检查,确保你在SELECT和GROUP BY中放置的内容合在一起是有意义的,因此在开始制定执行计划之前,它必须将查询作为一个整体来查看。

查询实际上不是按此顺序运行的(优化!)


实际上,数据库引擎并不是真的通过连接、然后过滤、然后再分组来运行查询,因为它们实现了一系列优化,只要重新排列执行顺序不改变查询结果,就可以重排以使查询运行得更快。

一个简单的例子说明了为什么需要以不同的顺序运行查询以使其快速运行,在这个查询中:

SELECT * FROMowners LEFT JOIN cats ON owners.id = cats.ownerWHERE cats.name = 'mr darcy'

如果你只需要查找3个名为“mr darcy”的猫,那么执行整个左连接并匹配这两个表中的所有行是非常愚蠢的 —— 首先对名为“mr darcy”的猫进行一些筛选要快得多。在这种情况下,先进行过滤不会改变查询结果!

实际上,数据库引擎还实现了许多其它优化,这些优化可能会使它们以不同的顺序运行查询,但不能再说了,老实讲,这方面我不是专家。


LINQ以FROM开始查询


LINQ(一种C#和VB.NET中的查询语法)使用的顺序为FROM ... WHERE ... SELECT。下面是一个LINQ查询的示例:

var teenAgerStudent = from s in studentList where s.Age > 12 && s.Age < 20 select s;

pandas(我喜欢的数据治理工具:https://github.com/jvns/pandas-cookbook)也基本上是这样工作的,尽管你不需要使用这种精确的顺序 — 我经常会这样编写pandas代码:

df = thing1.join(thing2) # like a JOINdf = df[df.created_at > 1000] # like a WHEREdf = df.groupby('something', num_yes = ('yes', 'sum')) # like a GROUP BYdf = df[df.num_yes > 2] # like a HAVING, filtering on the result of a GROUP BYdf = df[['num_yes', 'something1', 'something']] # pick the columns I want to display, like a SELECTdf.sort_values('sometthing', ascending=True)[:30] # ORDER BY and LIMITdf[:30]

这并不是因为pandas对如何编写代码强加了任何特定规则。只是按照JOIN / WHERE / GROUP BY / HAVING的顺序编写代码通常好理解。(不过,我经常会先放一个WHERE来提高性能,而且我认为大多数数据库引擎实际也会先执行WHERE)

在R的dplyr中,你还能使用不同的语法来查询诸如Postgres、MySQL或SQLite等SQL数据库,它们的顺序也更符合逻辑。

不知道这一点令我自己着实惊讶

我写了这样一篇博文,因为当我发现这个顺序的时候非常惊讶,我以前从来没有看到过它被这样写下来 — 它基本上解释了我凭直觉所知道的,关于为什么一些查询被允许而另一些不被允许的一切。所以我想把它写下来,希望它能帮助其他人理解如何编写SQL查询。

原文:https://jvns.ca/blog/2019/10/03/sql-queries-don-t-start-with-select/
声明:本文由CSDN翻译,转载请注明来源。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码