编写SQL查询的关键—SQL语句的执行顺序

2023-05-16

【文章标题】编写 SQL 查询的关键— SQL 语句的执行顺序

【文章作者】曾健生

【作者邮箱】 zengjiansheng1@126.com

【作者 QQ 190678908

【作者 MSN zengjiansheng1@hotmail.com

【作者博客】 blog.csdn.net/newjueqi

 

*******************************************************************************

    编写 SQL 语句是每个程序员应该具备的基本功。在实际开发过程中,需要编写比较复杂的 SQL 查询语句是必不可少的,但很多 SQL 书籍上不是简单的介绍一下就是出最终的查询语句,编写复杂 SQL 查询的具体思路却没有多少介绍,这不能不说是一种巨大的遗憾 , 看着一串无比复杂的 SQL 语句,没有掌握方法的话谁看了都会头晕 ^-^

回忆一下学习编程语言的经历( C++,java 等),我们一般都是先学习变量的定义,然后是流程控制语句,接着是函数,类等等。但我们在学习 SQL SQL 书籍上都普遍忽略了一个重要的方面: SQL 语句的执行顺序。 不知道是什么原因,这一点确实没被多少书籍提过。掌握了SQL语句的执行顺序的规律,就能较轻松的编写出复杂的 SQL 查询。

 

SQL 语句的执行顺序如下:

 

1 from 子句组装来自不同数据源的数据;

2 where 子句基于指定的条件对记录行进行筛选;

3 group by 子句将数据划分为多个分组;

4 、使用聚集函数进行计算;

5 、使用 having 子句筛选分组;

6 、计算所有的表达式;

7 、使用 order by 对结果集进行排序。

 

下面举一个简单的例子举例说明,假设有以下一张表 student

 

ID

Name

Age

1

Tom

23

2

Jack

25

3

Lucy

15

4

Anay

18

5

Bobby

21

 

要求通过 SQL 语句把年龄大于 20 的学生姓名查出来

 

SQL 语句如下:

 

Select name

From student

Where age>20

结果是:

Tom

Jack

Bobby

 

那对于这个简单的 SQL 语句,执行顺序是怎么样的呢?

1.       from 子句组装来自不同数据源的数据,简单点来说就是要确定查询的数据来自哪个表。如果 from 关键字后跟的表有两个或以上,就产生笛卡尔积。

2.       where 子句对每个记录行进行 筛选,把不符合条件的行筛选掉。

3.       针对符合条件的行执行相应的表达式操作,即 select 部分。

 

我们针对前面的写的 SQL 语句简单模拟一下执行过程:

1. 确定数据表,我们能根据 from 子句( From student )确定数据是来自下面的的表 student

   

ID

Name

Age

1

Tom

23

2

Jack

25

3

Lucy

15

4

Anay

18

5

Bobby

21

                                    1

 

2. 根据 where 子句中的条件( Where age>20 )筛选 记录行,请留意, where 子句的 筛选是对每一行 from 表中的每一行进行的。

(1)       对于第 1

1

Tom

23

 

Age=23>20, 符合条件

 

(2)       对于第 2

2

Jack

25

 

Age=25>20, 符合条件

 

(3)       对于第 3

3

Lucy

15

 

Age=15<20, 不符合条件

 

(4)       对于第 4

4

Anay

18

 

Age=18<20, 不符合条件

 

(5)       对于第 5

5

Bobby

21

 

Age=21>20, 符合条件

 

由上述的 (1)(2)(5) 可知,最终符合条件的记录为下表 2

 

ID

Name

Age

1

Tom

23

2

Jack

25

5

Bobby

21

                 2

 

4.       计算所有的表达式,即 Select name 部分,针对表 2 中的数据,最终符合条件的是 3 行,分别从每一行挑选出需要的字段值 name ,最终的结果如下表 3

Name

Tom

Jack

Bobby

                                    3

 

下面举一般比较复杂的例子,有 3 个表 teacher 表, student 表, tea_stu 关系表:


teacher
teaID name age
student
stuID name age
teacher_student
teaID stuID


要求用一条 sql 查询出这样的结果
1.
显示的字段要有老师 name, 每个老师所带的学生人数
2
只列出老师 age 45 以下,学生 age 12 以上的记录

 

先准备测试数据:

 

drop table if exists tea_stu;

drop table if exists teacher;

drop table if exists student;

      create table teacher(teaID int primary key,name varchar(50),age int);

      create table student(stuID int primary key,name varchar(50),age int);

      create table tea_stu(teaID int references teacher(teaID),stuID int references student(stuID));

insert into teacher values(1,' Tom',46), (2,' Jack',35) , (3,' Tony',36) , (4,' Lucy',37);

insert into student values(1,' Lili',11), (2,' Anay',15) , (3, 'Bobby',16) , (4, 'Jeff',17);

insert into tea_stu values(1,1), (1,2), (1,3),(2,2), (2,3), (2,4),(3,3), (3,4), (3,1),(4,4), (4,1), (4,2) , (4,3);

 

题目要求是列出 老师所带的学生数,条件是 老师 age 45 以下,学生 age 12 以上,最理想的情况是有下面的一个表 , 如图 1


                                  1

 

如果能构造一个图 1 的表,那么实现题目要求的 SQL 语句用下面的简单 SQL 查询就行:

 

select teacher.name, count(student.name)

from table

where teacher.age<45

   and student.age>12

group by teacher.name;

 

数据库中学生的信息和老师的信息是分别存放在 student, teacher 表中的,信息的关联只能依靠 tea_stu ,那么怎么构造图 1 的表呢?这时候可以用到表的关联,把这三个表的数据关联起来, 注意:只要是表的关联就会产生笛卡尔积,所以务必把笛卡尔积去掉。 关联表的最小粒度关联可以 去掉 笛卡尔积,具体的查询语句为:

select teacher.name, teacher.age,student.name,student.age

from teacher,student,tea_stu

where teacher.teaID=tea_stu.teaID

   and student.stuID=tea_stu.stuID

 

     所以综合以上所述,就能得出最终的查询语句

 

select teacher.name, count(student.name) student_num

from teacher,student,tea_stu

where teacher.teaID=tea_stu.teaID

   and student.stuID=tea_stu.stuID

   and teacher.age<45

   and student.age>12

group by teacher.name;

 

结果如图 2 所示:

 

                      2

 

 

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

编写SQL查询的关键—SQL语句的执行顺序 的相关文章

  • 如何在TOAD的DataGrid中显示sys_refcursor数据

    请我需要帮助 我搜索了很多并且变得更加困惑 我使用 Toad 9 7 25 并且我做了这个程序 在一个包中 PROCEDURE ReportaCC pfcorte IN DATE lcursor IN OUT SYS REFCURSOR I
  • MySQL 按主键排序

    某些 SQL 服务器允许使用通用语句 例如ORDER BY PRIMARY KEY 我不相信这适用于 MySQL 是否有任何此类解决方法可以允许跨多个表自动选择 或者是否需要查找查询来确定主键 我一直在研究的解决方法包括调用SHOW COL
  • 使用按位函数查询 BIT 字段时,MySQL 不使用索引

    我的 MySQL 表中有一个 BIT 类型的字段 我想使用位值存储记录的状态 例如 1 status1 2 status2 4 status3 8 status4 每条记录可以同时具有多种状态 对于 status1 和 status3 该值
  • 如何授予所有表的 REFERENCES 权限

    我必须授予REFERENCES登录权限说sql login 我可以给予资助REFERENCES对单个表的权限 例如 GRANT REFERENCES ON Mytable TO sql login 有什么办法可以授予REFERENCES允许
  • 限制 SQL Server 连接到特定 IP 地址

    我想将 SQL Server 实例的连接限制为特定 IP 地址 我想阻止来自除特定列表之外的任何 IP 地址的任何连接 这是可以在 SQL Server 实例或数据库中配置的东西吗 听起来像是你会使用Windows防火墙 http tech
  • Oracle 中的 SQL 调优 [关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何文章 链接可以让我找到 SQL 调优 Oracle 的示例 如果能用例子来解释那就太好了 我需
  • sql查询将两列与一列连接起来

    我在 MS Access 2010 中有 2 个表 如下所示 USERS u id u name LOAN l id l from ref users u id l to ref users u id l amount Users u id
  • 使用 MS Access 获取行的第一个实例

    EDITED 我有这个查询 我想SELECT表中记录的第一个实例petTable SELECT id pet ID FIRST petName First Description FROM petTable GROUP BY pet ID
  • 根据表sql中的行替换字符串中的字符

    我需要用一些映射的字符替换字符串中的字符列表 我有一个表 dbo CharacterMappings 有 2 列 CharacterToFilter 和 ReplacementCharacter 假设这个表中有3条记录 Filter Rep
  • 将 SQL 数据中的一行映射到 Java 对象

    我有一个 Java 类 其实例字段 以及匹配的 setter 方法 与 SQL 数据库表的列名相匹配 我想优雅地从表中获取一行 到 ResultSet 中 并将其映射到此类的实例 例如 我有一个 Student 类 其中包含实例字段 FNA
  • 使用两个日期之间的随机日期时间更新每一行

    我有一个专栏叫date created我希望每一行保存一个随机日期 日期距当前时间为 2 天 我正在运行以下查询 但它会更新具有相同随机日期的所有行 我希望每一行都是随机的并且不相同 update table set date create
  • 如何将可视选择的文本通过管道传输到 UNIX 命令并将输出附加到 Vim 中的当前缓冲区

    使用 Vim 我尝试将在可视模式下选择的文本通过管道传输到 UNIX 命令 并将输出附加到当前文件的末尾 例如 假设我们有一个 SQL 命令 例如 SELECT FROM mytable 我想做如下的事情
  • 如何在 Visual Studio 中更改 Azure 数据库表的列顺序

    我整个下午都在寻找在 MS Visual Studio 2022 中重新排序 Azure 数据库表列的方法 没有运气 在其他应用程序中 可以通过拖动或剪切和粘贴轻松重新排列列 这里无能为力 此时 我什至不确定可以在 VS 中移动列 我只对
  • 分层查询

    我希望我能够解释困扰我的问题 我有以下分层数据集 这只是 34K 记录的子集 PARENT ID CHILD ID EXAM TUDA12802 TUDA12982 N TUDA12982 TUDA12984 J TUDA12984 TUD
  • 独立对列进行排序,使得所有空值都位于每列的最后

    这是一个名为的示例表animal name color fox brown fox red dog gold 现在 我想要的是这样的结果 fox dog brown gold red 名称应该是结果的列 不同颜色值作为行 我的第一个想法是
  • 在sqlite SQL语句中与order by子句结合使用limit

    下面的两条 SQL 语句总是会产生相同的结果集吗 1 SELECT FROM MyTable where Status 0 order by StartTime asc limit 10 2 SELECT FROM SELECT FROM
  • sql server 按组排名

    问题看似简单 但我却无法理解 这是针对 sql 服务器的 what I have in a table What I need as a output cksum id cksum id 2162514679 204 2162514679
  • 如何从 PostgreSQL 中的时间戳列值提取一天中的时间(或小时)?

    我正在尝试从 PostgreSQL 中的 时间戳 列中提取一天中的时间 这是我的做法 但是 太糟糕了 知道如何做得更好吗 SELECT date part hour date demande text hours date part min
  • 对多个数据库执行 SQL 查询

    我知道我的帖子与该论坛中的其他帖子的标题非常相似 但我真的找不到我需要的答案 这是我的问题 我的 Windows Server 上运行着 SQL Server 在我的 SQL Server 中 我有大约 30 个数据库 它们都具有相同的表和
  • MySQL 按重复项从上到下排序

    我有一个lammer问题 因为我不是mysql专业人士 我有类似的字段 id color 1 red 2 green 3 yellow 4 green 5 green 6 red 我想按重复项进行分组 最常见的重复项先进行分组 所以应该这样

随机推荐

  • (转)cookie和session机制之间的区别与联系

    出处为中国JAVA手机网 lt www cnjm net gt http www cnjm net tech article1113 html 具体来说cookie机制采用的是在客户端保持状态的方案 它是在用户端的会话状态的存贮机制 xff
  • 30.因为绘画,我在豆瓣上认识了老婆

    导读 xff1a 这篇文章的上半部分 xff0c 是我2011年在豆瓣上发表的 五天学会绘画 书评 xff0c 我和老婆就相识于这个书评 后记部分 xff0c 是对绘画 xff0c 和用互联网方法找女友的一些思考 五天学会绘画 xff0c
  • 对太极拳中的“势”有所领悟

    文章标题 对太极拳中的 势 有所领悟 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 今天帮一个亲戚搬杂物 xff0c 从三楼的杂物房搬到一楼的花园 开始领悟 势 是搬一个很重
  • 本人写的Android上RSS阅读器简单介绍

    文章标题 本人写的 Android 上 RSS 阅读器简单介绍 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 个人博客 http blog csdn net newjueqi
  • 整合 ucenter 注册自动激活

    http my oschina net banbo blog 311691 应用整合 UCenter xff0c 同步注册到 Discuz 的用户 xff0c 在 Discuz 登录时得手动激活 xff0c 用户体验很不好 xff0c 不过
  • switch case语句用法详解

    switch 开关 的意思 xff0c 是一种 选择 语句 xff0c 它用法非常简单 switch 是多分支选择语句 说得通俗点 xff0c 多分支就是多个 if语句的组合 从功能上说 xff0c switch 语句和 if 语句完全可以
  • 32.APP后端处理表情的一些技巧

    app应用中文字夹带表情是个很常见的现象 甚至一些40多岁的大叔级用户 xff0c 也喜欢在自己的昵称中夹带表情 xff0c 在产品运营后发现这个现象 xff0c 彻底颠覆了我的世界观 在后台处理表情的时间 xff0c 我遇到过下面3个问题
  • 33.APP后端处理视频的方案

    在当前的app应用中 xff0c 到处都能看到视频的身影 xff0c 例如 xff0c 在社交类的app上 xff0c 用户可以拍摄属于自己的小视频 xff0c 并发布到相应得栏目 xff0c 增加和好友们互动的机会 后台常见的视频处理有以
  • 34.如何获取app(apk和ipa)中的资源

    移动互联网中 xff0c 主要的两个平台是android和ios xff0c android上文件的安装包是后缀名为apk的文件 xff0c ios上文件的安装包是后缀名为ipa的文件 xff0c 在本文分析一下这两种文件的特点 xff0c
  • 35.app后端搜索入门

    现在人们的网络生活已经离不开搜索了 xff0c 遇到不懂的问题 xff0c 想知道的事情 xff0c 搜索一下 xff0c 就知道答案 在app中 xff0c 最常见的搜索情景就是搜索用户 只有几百 xff0c 几千的用户量时 xff0c
  • 36.如何使用定时任务

    lt span style 61 34 font family Arial Helvetica sans serif background color rgb 255 255 255 34 gt 在app后台开发中 xff0c 经常需要执行
  • goroutine背后的系统知识

    http www sizeofvoid net goroutine under the hood o语言从诞生到普及已经三年了 xff0c 先行者大都是Web开发的背景 xff0c 也有了一些普及型的书籍 xff0c 可系统开发背景的人在学
  • 37.创业团队不是天堂

    在媒体的报导中 xff0c 创业公司一直都是充满情怀的 xff1a 宽松的工作环境 xff0c 不差的薪水 xff0c 不断高涨的融资额 xff0c 吃不完的零食和喝不完的饮料 xff0c 一群年轻人为了实现自己的梦想而一起奋斗 种种诱人的
  • java小程序(1)

    文章标题 java 小程序 xff08 1 xff09 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者声明 本人水平有限 xff0c 失误之处 xff0c 敬请各位指出
  • java小程序(2)

    文章标题 java 小程序 xff08 2 xff09 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者声明 本人水平有限 xff0c 失误之处 xff0c 敬请各位指出
  • java小程序(3)

    文章标题 java 小程序 xff08 3 xff09 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者声明 本人水平有限 xff0c 失误之处 xff0c 敬请各位指出
  • Python爬虫淘宝基于selenium抓取淘宝商品数据2021年测试过滑动验证

    配置一下 34 可能需要修改的参数 34 xff0c 就可以食用底部代码了 ps 可能已失效 本文章代码功能准备工作Python用到的库和准备工作 可能需要修改的参数在CMD中打开一个Chrome浏览器并启用端口给Selenium调用导入模
  • Android下的应用编程——用HTTP协议实现文件上传功能

    文章标题 Android 下的应用编程 用 HTTP 协议实现文件上传功能 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者 MSN zengjiansheng1 64 h
  • 从HTTP协议分析转发和重定向的区别

    文章标题 从 HTTP 协议分析转发和重定向的区别 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者 MSN zengjiansheng1 64 hotmail com 作
  • 编写SQL查询的关键—SQL语句的执行顺序

    文章标题 编写 SQL 查询的关键 SQL 语句的执行顺序 文章作者 曾健生 作者邮箱 zengjiansheng1 64 126 com 作者 QQ 190678908 作者 MSN zengjiansheng1 64 hotmail c