编写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语句的执行顺序 的相关文章

  • 如何在oracle中获取表作为输出参数

    我正在尝试将 Oracle 过程调用的 out 参数强制转换为对象 它不起作用 因为 据我了解 我需要定义一个映射 它告诉方法如何转换它 如果地图为空或未正确填充 则它默认为 STRUCT 类型的对象 在我的情况下这是错误的 我已经构建了一
  • C# 查询两个数据库的数据

    我目前有一个查询 我正在从两个不同的数据库获取数据 这些数据被附加到一个名为 accountbuys 的列表中 我的第一个表有三个数据条目 3个想要购买股票的帐户 下一张表有 17 个数据点 购买 17 只股票 I am merging t
  • SQL查询获取最后两条记录的DateDiff

    我有一个名为 Event 的表 其中 eventNum 作为主键 日期作为 SQL Server 2008 R2 中的 datetime2 7 我试图获取表中最后两行的日期并以分钟为单位获取差异 这就是我目前所拥有的 Select DATE
  • 如何显示 RSpec 测试生成的 SQL 查询日志?

    我正在为我的 Rails 3 应用程序编写规范 我想测试数据库事务是否真的有效 如果能够看到我的应用程序在规范驱动下生成的 sql 查询 这将非常有帮助 有没有办法像在 Rails 控制台中一样查看查询 我正在使用 Rails 3 0 9
  • Solr 增量导入不起作用

    我使用的是solr 4 2 请注意 完全导入有效 但增量导入却无效 增量导入不会给出任何错误 但不会获取任何更改 这是数据配置文件
  • SQL Server查询麻烦,多对多关系

    不知道如何用一行字来表达这个问题 对标题表示歉意 我的数据库中有3个表 例如 Shop Item 商店库存 Shop 和 Item 具有多对多关系 因此 ShopStock 表将它们链接起来 ShopStock 中的字段是 ID ShopI
  • 从 SQL Server 2012 查询结果中减去小时数

    我正在 SQL Server 2012 Management Studio 中的警报系统信号自动化平台数据库上运行查询 但遇到了一些问题 我的查询运行得很好 但我无法将结果细化到我想要的水平 我正在选择一些格式为的列DATETIME 我只想
  • 如果外键不存在,则添加外键约束(或者如果存在则删除外键约束)而不使用名称?

    我发现创建查询很困难 假设我有一个产品和品牌表 我可以使用此命令添加外键 ALTER TABLE Products ADD FOREIGN KEY BrandID REFERENCES Brands ID 但我只需要在外键不存在时运行此命令
  • SQL Server中主键和唯一索引的区别[重复]

    这个问题在这里已经有答案了 我的公司目前正在重写我们最近获得的一个应用程序 我们选择使用 ASP net mvc4 来构建这个系统 并使用实体框架作为我们的 ORM 我们收购的公司的前任所有者非常坚定地要求我们使用他们的旧数据库 并且不对其
  • Oracle SQL——从字符串中删除部分重复项

    我有一个表 其中有一列包含字符串 如下所示 static text here 1abcdefg1abcdefgpxq 从这个字符串1abcdefg重复两次 所以我想删除该部分字符串 然后返回 static text here 1abcdef
  • SQL 用新值替换旧值

    我有一个名为tbl Products 其中有一列名为articlenumber并且充满了像这样的数字s401 s402 etc 我生成了一个包含新商品编号的列表 它将替换旧的商品编号 s401 I00010 s402 I00020 s403
  • play20 ebean 生成的 sql 在 postgresql 上抛出语法错误

    我正在尝试使用 postgresql 来启动我的 play20 应用程序 以便我可以使用并稍后部署到 Heroku 我跟着这个answer https stackoverflow com questions 12195568 errors
  • 使用另一个表中的数据查找并替换 MySQL 中的字符串

    我有两个 MySQL 表 我想使用另一个表中的数据查找和替换一个表中的文本字符串 Table texts messages thx guys i think u r great thx again u rock Table dictiona
  • 为什么 sql 字段名称中不应该包含逗号?

    人们一直告诉我列名中不应包含空格 我只是想知道 这是为什么 这是我为学校创建的一些数据库表遇到的问题 字段名称包括 Preble 和 Darke 相反 它们需要是 普雷布尔县 俄亥俄州 和 达克县 俄亥俄州 如果它们是行名称 我只需创建一个
  • Oracle 获取列值发生变化的行

    假设我有一张桌子 比如 ID CCTR DATE 1 2C 8 1 2018 2 2C 7 2 2018 3 2C 5 4 2017 4 2B 3 2 2017 5 2B 1 1 2017 6 UC 11 23 2016 还有其他字段 但我
  • 返回行位置 - Postgres

    我返回一个带有位置的表 select from select row number over as position from organization result where data1 Hello 返回这个 这是正确的 data1 H
  • 如何在SQL Server数据库表列中存储图像[重复]

    这个问题在这里已经有答案了 我有一张名为FEMALE在我的数据库中 它有ID as Primary Key 它有一个Image column 我的问题是如何使用 SQL 查询存储图像 尝试一下 insert into tableName I
  • 具有 LINQ 支持的最完整的 ORM?

    我正在寻找一个提供完整或接近完整的 LINQ 支持的 ORM LINQ 到 SQL 支持 LINQ 内部的所有内容 Contains Math Log 等 在不创建新数据上下文的情况下无法预先加载关系属性 ADO NET 实体框架 糟糕的
  • 如何打印Oracle中过程的定义?

    oracle中有没有办法查看过程的结构是什么 我正在尝试记录并运行程序 并希望将实际的程序结构存储在我的日志中 您可以查询ALL SOURCE table SELECT text FROM all source WHERE owner lt
  • SQL 大表中的随机行(使用 where 子句)

    我有一个网站 人们可以在其中对汽车进行投票 向用户展示 4 辆汽车 他 她可以投票选出他们最喜欢的汽车 桌子cars有重要的列 car id int 10 not auto increment so has gaps views int 7

随机推荐

  • (转)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