很多 SQL 查询都是以 SELECT 开始的。不过,最近我跟别人解释什么是窗口函数,我在网上搜索”是否可以对窗口函数返回的结果进行过滤“这个问题,得出的结论是”窗口函数必须在 WHERE 和 GROUP BY 之后,所以不能”。于是我又想到了另一个问题:SQL 查询的执行顺序是怎样的?

好像这个问题应该很好回答,毕竟自己已经写了上万个 SQL 查询了,有一些还很复杂。但事实是,我仍然很难确切地说出它的顺序是怎样的。

SQL 查询的执行顺序

于是我研究了一下,发现顺序大概是这样的。SELECT 并不是最先执行的,而是在第五个。

这张图回答了以下这些问题

这张图与 SQL 查询的语义有关,让你知道一个查询会返回什么,并回答了以下这些问题:

  • 可以在 GRROUP BY 之后使用 WHERE 吗?(不行,WHERE 是在 GROUP BY 之后!)
  • 可以对窗口函数返回的结果进行过滤吗?(不行,窗口函数是 SELECT 语句里,而 SELECT 是在 WHERE 和 GROUP BY 之后)
  • 可以基于 GROUP BY 里的东西进行 ORDER BY 吗?(可以,ORDER BY 基本上是在最后执行的,所以可以基于任何东西进行 ORDER BY)
  • LIMIT 是在什么时候执行?(在最后!)

但数据库引擎并不一定严格按照这个顺序执行 SQL 查询,因为为了更快地执行查询,它们会做出一些优化,这些问题会在以后的文章中解释。

所以:

  • 如果你想要知道一个查询语句是否合法,或者想要知道一个查询语句会返回什么,可以参考这张图;
  • 在涉及查询性能或者与索引有关的东西时,这张图就不适用了。

混合因素:列别名

有很多 SQL 实现允许你使用这样的语法:

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

从这个语句来看,好像 GROUP BY 是在 SELECT 之后执行的,因为它引用了 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 中的东西是有效的,所以会在生成执行计划之前对查询做一次整体检查。

数据库可能不按照这个顺序执行查询(优化)

在实际当中,数据库不一定会按照 JOIN、WHERE、GROUP BY 的顺序来执行查询,因为它们会进行一系列优化,把执行顺序打乱,从而让查询执行得更快,只要不改变查询结果。

这个查询说明了为什么需要以不同的顺序执行查询:

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

如果只需要找出名字叫“mr darcy”的猫,那就没必要对两张表的所有数据执行左连接,在连接之前先进行过滤,这样查询会快得多,而且对于这个查询来说,先执行过滤并不会改变查询结果。

数据库引擎还会做出其他很多优化,按照不同的顺序执行查询,不过我并不是这方面的专家,所以这里就不多说了。

LINQ 的查询以 FROM 开头

LINQ(C#和 http://VB.NET 中的查询语法)是按照 FROM…WHERE…SELECT 的顺序来的。这里有一个 LINQ 查询例子:

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

pandas 中的查询也基本上是这样的,不过你不一定要按照这个顺序。我通常会像下面这样写 pandas 代码:

df = thing1.join(thing2)      # JOIN
df = df[df.created_at > 1000] # WHERE
df = df.groupby('something', num_yes = ('yes', 'sum')) # GROUP BY
df = df[df.num_yes > 2]       # HAVING, 对 GROUP BY 结果进行过滤
df = df[['num_yes', 'something1', 'something']] # SELECT, 选择要显示的列
df.sort_values('sometthing', ascending=True)[:30] # ORDER BY 和 LIMIT
df[:30]

这样写并不是因为 pandas 规定了这些规则,而是按照 JOIN/WHERE/GROUP BY/HAVING 这样的顺序来写代码会更有意义些。不过我经常会先写 WHERE 来改进性能,而且我想大多数数据库引擎也会这么做。

R 语言里的 dplyr 也允许开发人员使用不同的语法编写 SQL 查询语句,用来查询 Postgre、MySQL 和 SQLite。

原文链接:SQL queries don’t start with SELECThttps://jvns.ca/blog/2019/10/03/sql-queries-don-t-start-with-select/

.net函数查询_SQL查询语句总是先执行SELECT?你们都错了!相关推荐

  1. java中当前时间查询_SQL 查询当前时间

    Mysql: select date_format(now(),'%Y-%m-%d'); Oracle: Oracle中如何获取系统当前时间进行语句的筛选是SQL语句的常见功能 获取系统当前时间 da ...

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

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

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

    很多 SQL 查询都是以 SELECT 开始的.不过,最近我跟别人解释什么是窗口函数,我在网上搜索"是否可以对窗口函数返回的结果进行过滤"这个问题,得出的结论是"窗口函数 ...

  4. SQL 查询语句总是先执行 SELECT?

    点击上方"朱小厮的博客",选择"设为星标" 后台回复"1024"领取惊喜资料 很多 SQL 查询都是以 SELECT 开始的.不过,最近我跟 ...

  5. mysql sql decode函数用法_SQL查询中DECODE函数和CASE WHEN 比较

    一,DECODE函数 其基本语法为: Sql代码DECODE(value, if1, then1, if2, then2, if3, then3,...ifn, thenn, else) DECODE ...

  6. order by 子查询_SQL查询语法

    平常大家对于sql可能不是太陌生,经常使用sql来进行数据的存储等操作.今天我就来分享一下最简单的也是最基本的SQL查询类的语法操作.如下图所示,为PG的语法,应是涵盖了了查询的80%的用法. 一.关 ...

  7. knex 单表查询_SQL查询构建器 knex.js

    授权协议: MIT 开发语言: JavaScript 操作系统: 跨平台 软件介绍 knex.js 是一个查询构建器,用于 PostgreSQL, MySQL 和 SQLite3.它设计灵活,轻便和有 ...

  8. java销售额查询_SQL查询每月查找总销售额 - oracle

    我有两个表,产品(pid,pname,quantityinhand,价格,折扣)购买(pid,qty,p_time,total_price)//其中qty是销售单位数 . 我需要找到pname,pda ...

  9. sql中“delete from 表名”表示_SQL查询语句知识点总结

    为什么要学习SQL? 数据分析岗位的基础技能:SQL语句和会使用SQL语句操纵数据库软件: 数据量增大的工具需求:excel处理十万以内的数据:数据量增大,需要使用更快速便捷的工具分析数据. SQL知 ...

最新文章

  1. 中国电子学会青少年编程能力等级测试图形化一级编程题:小狗进圈
  2. 卧槽!看不懂这些动图,你不配做个程序员
  3. ANSI编码和标准代码页(code page)
  4. php会话(session)生命周期概念介绍及设置更改和回收
  5. SAP 与 JSON 接口实施案例一
  6. 【数据结构与算法】【算法思想】分治算法
  7. [Android][Android Studio] *.jar 与 *.aar 的生成与*.aar导入项目方法
  8. 什么人不在生死簿_地府在孙悟空划掉生死簿以后,因为什么原因不组织重写?...
  9. python线性输出_Python实现基本线性数据结构
  10. Scala class
  11. 通过图灵测试!Google掌舵人说“打电话AI”是一次非凡突破
  12. JavaScript中的字面量
  13. C语言库函数的哈希表使用方法
  14. 排队叫号python编程_一种自主选时排队叫号算法
  15. EXCEL中怎样能复制公式得来的数据(选择性粘贴)
  16. C# 读写视频文件
  17. [小O地图-XOMAP] - 功能简介
  18. html级联选择器,jquery实现 级联选择器
  19. django 中的聚合和分组 F查询 Q查询 事务cookies和sessions 066
  20. spo2数据集_氧仪主要测量指标分别为脉率、血氧饱和度、灌注指数(PI)

热门文章

  1. Cygwin中如何像在Ubuntu中一样安装软件
  2. R语言第九讲 验证集法
  3. vue 接口节流_vue输入节流,避免实时请求接口的实例代码
  4. PAT乙类1007之素数对猜想
  5. Spring Boot开发Web应用
  6. 开源开放 | 欢迎选修浙江大学《知识图谱》开放共享慕课
  7. 论文浅尝 | BoxE:一种基于Box的知识图谱表示学习模型
  8. DTW动态时间规整算法
  9. 军事武器知识图谱构建与自动问答项目QAonMilitaryKG
  10. Linux关闭Tomcat服务器出现无法关闭 :8005端口未启动