SQL查询是从Select开始的吗?

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

(这里是一篇推特: 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

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

此图是关于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 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中放置的内容合在一起是有意义的,因此在开始制定执行计划之前,它必须将查询作为一个整体来查看。

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

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

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

SELECT * FROM

owners LEFT JOIN cats ON owners.id = cats.owner

WHERE 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代码:

结尾

查漏补缺:Java岗 千+道面试题Java基础+全家桶+容器+反射+异常等

这不止是一份面试清单,更是一种”被期望的责任“,因为有无数个待面试者,希望从这篇文章中,找出通往期望公司的”钥匙“,所以上面每道选题都是结合我自身的经验于千万个面试题中经过艰辛的两周,一个题一个题筛选出来再次对好答案和格式做出来的,面试的答案也是再三斟酌,深怕误人子弟是小,影响他人仕途才是大过,也希望您能把这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
这篇文章分享给更多的朋友,让他帮助更多的人,帮助他人,快乐自己,最后,感谢您的阅读。

由于细节内容实在太多啦,在这里我花了两周的时间把这些答案整理成一份文档了,在这里只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 16
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值