作者 | Julia Evans

译者 | 王雪迎     责编 | 孙胜

出品 | CSDN(ID:CSDNnews)

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

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

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

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

1、SQL查询按此顺序进行

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

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

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

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

l FROM/JOIN 和所有的 ON 条件
l WHERE
l GROUP BY
l HAVING
l SELECT(包括窗口函数)
l ORDER BY
l LIMIT

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

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

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

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

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

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

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

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

所以:

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

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

4、混淆因素:列别名

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

SELECT CONCAT(first_name, ' ', last_name) AS full_name, count(*)
FROM table
GROUP 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 table
GROUP BY CONCAT(first_name, ' ', last_name)

并且首先运行GROUP BY。

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

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

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

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

SELECT * FROM
owners LEFT JOIN cats ON owners.id = cats.owner
WHERE cats.name = 'mr darcy'

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

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

6、LINQ以FROM开始查询

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

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

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

df = thing1.join(thing2)      # like a JOIN
df = df[df.created_at > 1000] # like a WHERE
df = df.groupby('something', num_yes = ('yes', 'sum')) # like a GROUP BY
df = df[df.num_yes > 2]       # like a HAVING, filtering on the result of a GROUP BY
df = df[['num_yes', 'something1', 'something']] # pick the columns I want to display, like a SELECT
df.sort_values('sometthing', ascending=True)[:30] # ORDER BY and LIMIT
df[: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/

最后推荐一下我们的星球:由菜鸟学Python原班人马建了一个投资星球,汇聚一批喜欢投资的朋友一起分享投资的技巧,不限于基金,股票等其他品种,提高自己的财商,一起读书打卡,欢迎加入。
推荐阅读:入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|年度爆款文案1).卧槽!Pdf转Word用Python轻松搞定!2).学Python真香!我用100行代码做了个网站,帮人PS旅行图片,赚个鸡腿吃3).首播过亿,火爆全网,我分析了《乘风破浪的姐姐》,发现了这些秘密 4).80行代码!用Python做一个哆来A梦分身 5).你必须掌握的20个python代码,短小精悍,用处无穷 6).30个Python奇淫技巧集 7).我总结的80页《菜鸟学Python精选干货.pdf》,都是干货 8).再见Python!我要学Go了!2500字深度分析!9).发现一个舔狗福利!这个Python爬虫神器太爽了,自动下载妹子图片点阅读原文,领AI全套资料!

SQL查询是从Select开始的吗?相关推荐

  1. 删除表的sql命令是什么_【技术干货】30个最适合初学者的SQL查询

    毫无疑问,SQL或结构化查询语言是最流行的编程语言之一,尤其是因为它具有访问和修改数据库中数据的功能.SQL与数据库接口的基本用法是其流行的最重要原因. 关于SQL的最基本方面之一就是查询.基本上,S ...

  2. sql 找到最近的值_数据分析——SQL查询(常用函数)

    SQL入门推荐书籍--<SQL必知必会>.猴子的live课程--<从零开始学SQL> [基本SQL查询语句] select 选择输出字段 from 摘自某表 as 取别名(如果 ...

  3. 【mysql技术内幕1】mysql基础架构-一条SQL查询语句是如何执行的

    文章目录 1 一条SQL查询语句是如何执行的 2 mysql体系结构 3 InnoDB存储引擎 4 总结 1 一条SQL查询语句是如何执行的 ​ 通常我们使用数据库,都是将数据库看成一个整体,我们的应 ...

  4. postgre sql 括字段_【技术干货】30个最适合初学者的SQL查询

    毫无疑问,SQL或结构化查询语言是最流行的编程语言之一,尤其是因为它具有访问和修改数据库中数据的功能.SQL与数据库接口的基本用法是其流行的最重要原因. 关于SQL的最基本方面之一就是查询.基本上,S ...

  5. sql查询将科学计数法转为数字型

    忘了是哪来的数据,指标值value有科学计数法的情况,不方便做统计计算,所以就有了需要将科学计数法转为数字型的场景,sql查询如下: select convert(sum(volumes),decim ...

  6. navicat使用及SQL查询语法

    navicat使用及SQL查询语法目录复制 数据库工具连接使用 1.1新建mysql数据库 1.2工具如果使用 1.3用工具执行查询语句 SQL语法 2.1简介 2.2 SQL 查询数据 (SELEC ...

  7. asp sql查询过滤空格_【技术干货】30个最适合初学者的SQL查询

    海牛学院的 | 第 598 期 本文预计阅读 | 11 分钟 毫无疑问,SQL或结构化查询语言是最流行的编程语言之一,尤其是因为它具有访问和修改数据库中数据的功能.SQL与数据库接口的基本用法是其流行 ...

  8. SQL查询语句 select 详解

    查询select: 1.单表查询 2.多表查询 3.嵌套查询分类 1)单表查询 2)多表查询 A.连接查询 B.子查询 ①一般子查询 ②相关子查询*************************** ...

  9. SQL 查询总是先执行SELECT语句吗?你们都错了!

    点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 译者:无明 链接:infoq.cn/article/Oke8hgi ...

  10. SQL查询语句总是先执行SELECT?你们都错了。。。

    来源 | infoq.cn/article/Oke8hgilga3PTZ3gWvbg 很多 SQL 查询都是以 SELECT 开始的.不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否 ...

最新文章

  1. HTTP metadata数据
  2. sqlserver、oracle数据库排序空值null问题解决办法
  3. 亲和数(信息学奥赛一本通-T1154)
  4. python 任务计划程序_10.Selenium+Python+任务计划程序实现定时发送邮件
  5. 灰度拉伸python_灰度变换之灰度线性拉伸(算法1)
  6. 美国重金投资3D芯片项目!MIT+美独资公司攻关,旨在继续领先中国
  7. iframe和response.sendRedirect()跳转到父页面的问题
  8. ppt模板怎样用到html中,手把手教你怎么选用PPT模板
  9. Servlet容器的启动过程。
  10. OA系统-部门和员工管理模块
  11. 可能是全网唯一办法:解决粘滞键(shift)键一直按下,在配置中心无法关闭_v1.0.0
  12. 【递推】种萝卜 C++题解
  13. 键盘没有NumLock这个键 怎样解锁数字键盘?
  14. 为什么Excel文件打开后全部格式都…
  15. Vue首屏加载等待动画
  16. 微库为8亿会员的微信“偷偷”干了什么?
  17. 2010年度先进单位、先进个人、优秀辅导教师名录
  18. mysql查询当月数据_MySQL查询当天当月数据 | 小灰灰博客
  19. Python: 打包发布到PyPi及踩坑经历
  20. 利用Fabry-Perot扫描干涉仪测量激光的纵模

热门文章

  1. hbase mysql hdfs_Alex的Hadoop菜鸟教程:第8课Sqoop1导入Hbase以及Hive
  2. 坚持练字一年是什么样的体验?
  3. mysql面试必会6题经典_经典sql面试题及答案第7期
  4. 制作一个模拟Windows启动界面的文本进度条python
  5. Android实现Telnet客户端
  6. GB28181协议——布防和报警订阅
  7. DoIP(一)——基础概念
  8. 直线段的矢栅转换算法(DDA算法、中心画线算法、Bresenham算法)
  9. JavaScript - OOP编程思想
  10. 计算机485通讯原理,用RS-485设计的多机通信接口电路