1、初级 SQL 开发指南Select 语句概要数据库中数据的提取(查询)使用 select 语法,主要有以下几点作用 提取的数据(搜索) 提取的数据进行排序(排序) 执行计算或汇总Select 文表达方法SQL 文处理 Select 语句顺序步骤我们将说明数据库在处理查询的时候,不同阶段都会产生中间结果表.这些产生出来的中间结果表都是在数据库后台运行的我们无法观察到.我们最终看到的数据就是最后的中间结果表.从句 from 从数据库中检索出来第一个中间结果表开始,到 select 从句结束.分为以下几步1 通过 from 关键字将要查询的表中的所有数据读取到中间结果表。 (包括表中所有数据行与列,
2、行数不变,列数不变)2 在 where 关键字后面加上要读取数据的条件,生成一个新的中间结果表。3 如果业务需要分组,可以通过 Group by 将视图进行分组,在次生成一个新的中间结果表。4 使用 having 关键字为分组后的逻辑视图进行条件筛选,来生成一个中间结果表。5 通过 select 语句在最终的中间结果表中选择列。From 指定查询的表having 分组条件select 选择列Where 选择满足条件的行Group by 分组Select 列名 1,列名 2 查询要显示的列结果From 表名 数据库中表名Where 查询条件 条件表达式查询数据时,数据库后台中间结果表变化过程我们
3、将从数据库在执行 SQL 查询计划的时候,数据库内部的变化与运行的原理来理解 SQL 语句执行过程.(数据库中分为 2 种视图,1 为物理视图通过 create view 语句创建,2 为逻辑视图,就是我们提到的中间结果表)(人员信息表)编号 名称 部门 职务 年龄 性别 电话122 李晶晶 人力 职员 26 女 2234555123 张金 人力 职员 29 男 3322123124 王力 机材 经理 35 男 2245553125 李心 机材 职员 21 女 3332233例:给出所有职务为职员的用户名称,部门,电话.步骤一 执行 from 表名称 (人员信息表),数据库会在(人员信息表)表
4、中进行一个全表扫描,将所有表信息放入一个逻辑视图中, 逻辑视图包括表中的全部的行于列的数据.步骤一 产生的中间结果表122 李晶晶 人力 职员 26 女 2234555123 张金 人力 职员 29 男 3322123124 王力 机材 经理 35 男 2245553125 李心 机材 职员 21 女 3332233步骤二 通过 where 职务=职员 的判断条件将步骤一中产生的逻辑视图的数据进行过滤,将满足条件的行产成一个新的逻辑视图.步骤二 产生的中间结果表122 李晶晶 人力 职员 26 女 2234555123 张金 人力 职员 29 男 3322123125 李心 机材 职员 21
5、女 3332233步骤三 通过 select 名称,部门,电话 语句把步骤二的逻辑视图中,名称,部门,电话列的数据取出生成一个新视图.select 语句指定那些列必须出现在最终逻辑视图中.步骤三 产生的中间结果表李晶晶 人力 2234555张金 人力 3322123李心 机材 3332233步骤四 将产生的逻辑视图发送到客户端.完成本次 SQL 查询计划.SQL 编写顺序与逻辑视图生成过程.多表信息查询表达方法当多个表进行联合查询的时候,会发生一张表(A)中的数据行乘以别一张表(B)中的数据行,也就是 A*B=所有查询数据.该结果产生的合并表数据被我们称为笛卡儿积.通常笛卡儿积会产生很多重复行
6、的数据,我们要使用连接条件也就是 A 表和 B 表中指定的连接列来过滤掉重复和多余的笛卡儿积.1 通过 from 关键字后的表名称,到数据库中将表 A 和表 B 两个表中所有表数据取出到两个对应的中间结果表中.2 数据库会将两个中间结果表合成一个中间结果表,而生成的这个中间结果表就是我们说的笛卡儿积.它的数据内容就是 A 表的中间结果*B 表的中间结果.为A*B 的数学关系3 在笛卡儿积中间结果表中通过 where 关键字选择符合列连接条件或者满足条件的行,将符合条件的行再生成一个中间结果表.4 在中间结果表中通过 select 关键字选择列,生成最终中间结果表,把它传给客户端.Select
7、名称,部门,电话 步骤三 生成最终逻辑视图From 员工信息表 步骤一 生成全表逻辑视图Where 职务=职员 步骤二 生成符合条件的逻辑视图Select 表 1.列名, 表 2.列名 选择要表示的列From 表 1, 表 2 要合并查询的表Where 表 1.ID1=表 2.ID1 多表连接条件A 表 B 表笛卡儿积A*B 中间结果表WHERE 选择符合条件的行,生成中间结果表SELECT 选择列生成最终结果多表合并查询时数据库后台中间结果表变化过程(人员信息表)编号 名称 部门 ID 年龄 性别 电话122 李晶晶 1 26 女 2234555123 张金 1 29 男 332212312
8、4 王力 2 35 男 2245553125 李心 3 21 女 3332233( 部门信息表)部门 ID 部门名称 部门简称1 人力资源部 人力2 运行维护部 运维3 财务部 财务例:查询部门简称为财务的人员信息,信息包括人员名称,部门简称, 部门名称,性别,电话步骤一 执行 from 人员信息表,部门信息表.数据库对(人员信息表), ( 部门信息表)2 张表进行一个全表扫描.然后将 2 个表的数据生成一个笛卡儿积的逻辑视图.执行这个(select * from 人员信息表,部门信息表 )SQL 不加连接列条件我们就可以看到一个笛卡儿积数据.步骤一 产生的中间结果表的笛卡儿积编号 名称 部门
9、 ID 年龄 性别 电话 部门 ID 部门名称 部门简称122 李晶晶 1 26 女 2234555 1 人力资源部 人力122 李晶晶 1 26 女 2234555 2 运行维护部 运维122 李晶晶 1 26 女 2234555 3 财务部 财务123 张金 1 29 男 3322123 1 人力资源部 人力123 张金 1 29 男 3322123 2 运行维护部 运维123 张金 1 29 男 3322123 3 财务部 财务124 王力 2 35 男 2245553 1 人力资源部 人力124 王力 2 35 男 2245553 2 运行维护部 运维124 王力 2 35 男 224
10、5553 3 财务部 财务125 李心 3 21 女 3332233 1 人力资源部 人力125 李心 3 21 女 3332233 2 运行维护部 运维125 李心 3 21 女 3332233 3 财务部 财务步骤二 通过连接列条件取出步骤一逻辑视图中符合条件的行,生成一个新的逻辑视图. 连接列条件为 where 人员信息表.部门 ID=部门信息表. 部门 ID步骤二产生的中间结果表编号 名称 部门 ID 年龄 性别 电话 部门 ID 部门名称 部门简称122 李晶晶 1 26 女 2234555 1 人力资源部 人力123 张金 1 29 男 3322123 1 人力资源部 人力124
11、王力 2 35 男 2245553 2 运行维护部 运维125 李心 3 21 女 3332233 3 财务部 财务步骤三 通过判断条件 and 部门信息表 .部门简称=财务 取出上一个逻辑视图中符合条件的行.生成一个新的逻辑视图步骤三 产生的中间结果表编号 名称 部门 ID 年龄 性别 电话 部门 ID 部门名称 部门简称125 李心 3 21 女 3332233 3 财务部 财务步骤四 通过 select 人员信息表.人员名称,部门信息表.部门简称,人员信息表.部门信息表.部门名称, 人员信息表.性别, 人员信息表.电话 选择要列,生成一个最终逻辑视图.步骤四 最终中间结果表名称 部门名称
12、 部门简称 性别 电话李心 财务部 财务 女 3332233步骤五 将产生的逻辑视图发送到客户端.完成本次 SQL 查询计划.SQL 编写顺序与逻辑视图生成过程.总结通过上面的介绍,我们知道了数据库在执行查询 SQL 计划时逻辑视图变化过程.我们在编写查询计划的时候,需要按照逻辑视图变化过程来编写,先写 from 再写 where 最后 select 这个顺序.在多表的时候,需要 where 来指定表的接合条件来过滤笛卡儿积.Select 人员信息表.人员名称, 步骤四 选择列部门信息表.部门简称,人员信息表.部门名称,人员信息表.性别, 人员信息表.电话From 人员信息表,部门信息表 步骤
13、一 合并表数据 Where 人员信息表.部门 ID=部门信息表. 部门 ID 步骤二 选择部门 ID 相等行And 部门信息表.部门简称=财务 步骤三 选择部门名称为财务的行多表合并查询时候的内连接与外连接在上面我们使用多表查询的时候,对笛卡儿积的处理是使用 where 加列连接条件.这种方法也被称为隐性连接.在 SQL 标准语句中有一种 from 从句的扩展方法可以直接完成上面的功能. 这种从句的扩展方法也被成为显性内连接.关键字为 inner join on 后边指定连接条件。Inner join 表达方法数据库中有以下 2 张表(人员信息表)编号 名称 部门 ID 年龄 性别 电话122
14、 李晶晶 1 26 女 2234555123 张金 1 29 男 3322123124 王力 2 35 男 2245553125 李心 3 21 女 3332233( 部门信息表)部门 ID 部门名称 部门简称1 人力资源部 人力2 运行维护部 运维3 财务部 财务运行以下 SQL 文-获得结果-编号 名称 部门 ID 年龄 性别 电话 部门 ID 部门名称 部门简称122 李晶晶 1 26 女 2234555 1 人力资源部 人力123 张金 1 29 男 3322123 1 人力资源部 人力124 王力 2 35 男 2245553 2 运行维护部 运维125 李心 3 21 女 3332
15、233 3 财务部 财务Select 表 1.列名, 表 2.列名 要选择的列From 表 1 inner join 表 2 on 表 1.ID1=表 2.ID1 Where 行选择条件SELECT * FROM 人员信息表 inner join 部门信息表 on 人员信息表.部门 ID=部门信息表.部门 IDFrom 可以通过内连接直接获得到要得到的数据结果,而不产生笛卡儿积现象.我们也可以通过上面 WHERE 列连接条件的方法得到一个与内连接(inner join on) 相同的数据结构.可以说 WHERE 列连接条件和(inner join on)都是内连接.Where 是隐性连接, (
16、inner join on)为显性连接,大家可以根据个人习惯来选择那种方式来进行多表连接.内连接分为 2 种连接方法1 显性连接,FROM INNER JOIN ON 2 隐性连接,where 列的关联条件。在低版本数据库中,显性连接和隐性连接执行效率上会有差别,在现在的数据库中基本没有区别了。完全根据个人习惯或者项目要求来选择使用哪种连接方式。外连接虽然我们学会使用了内连接,但是还有很多复杂情况内连接无法解决.SQL 还给我们提供了一种连接方法叫外连接.在外连接的表合并过程中,我们要定义一个驱动表,以驱动表为基础与其他表进行多表合并的过程叫外连接. 外连接分为左连接和右连接,显性连接 fro
17、m (LEFT JOIN ON 列连接条件 ,RIGHT JOIN ON 列连接条件)隐性连接 where 列连接条件(+)=列连接条件,列连接条件 =列连接条件(+) 表示.SQL 表达方式显性连接隐性连接如果你想以表 1 为驱动表就在 where 表 1=表 2(+) 为左表连接如果你想以表 2 为驱动表就在 where 表 1(+)=表 2 为右表连接SELECT *FROM 人员信息表,部门信息表 WHERE 人员信息表.部门 ID=部门信息表.部门 ID SELECT *FROM 表 1 (left or right) join 表 2 on 表 1.ID1=表 2.ID1 WHER
18、E 选择行条件SELECT *FROM 表 1,表 2 WHERE 表 1.ID1=表 2.ID1(+) and 选择行条件或者 表 1.ID1(+)=表 2.ID1 and 选择行条件数据库有以下 3 张表(人员信息表)编号 名称 部门 ID 年龄 职务 ID 性别 电话122 李晶晶 1 26 1 女 2234555123 张金 1 29 null 男 3322123124 王力 2 35 1 男 2245553125 李心 3 21 2 女 3332233126 鲁兰 null 232 null 女 3486443( 职务信息表)职务 ID 职务名称1 职员2 经理( 部门信息表)部门
19、ID 部门名称1 人力资源部2 运行维护部3 财务部执行以下 SQL 时-获得结果-编号 名称 部门 ID 年龄 职务 ID 性别 电话 职务 ID 职务名称122 李晶晶 1 26 1 女 2234555 1 职员123 张金 1 29 null 女 3322123 null null124 王力 2 35 1 男 2245553 1 职员125 李心 3 21 2 女 3332233 2 经理126 鲁兰 null 232 null 女 3486443 null null我们以人员信息表为驱动表进行多表合并查询. 驱动表所有信息全部显示,和职务表没有关联条件人员信息也将被查询出来.如果我们
20、使用内连接,和职务表没有关联的那条信息将无法被查询出来。上面的结果粉色部分数据在内连接的时候不能被查询出来。只有我们以人员信息表为驱动表进行外连接才可以得到上面的数据。SELECT *FROM 人员信息表 left join 职务信息表 on 人员信息表.职务 ID=职务信息表.职务 ID 或者SELECT *FROM 人员信息表 ,职务信息表 WHERE 人员信息表.职务 ID=职务信息表.职务 ID(+)例:查询出部门名称不能为空的所有女性的员工名称, 部门名称,职务名称信息.SQL 执行过程如下图所示隐性连接 SQL 文部门 ID 为内连接条件人员信息表 部门信息表 职务信息表人员信息表
21、与部门信息表内连接中间结果表人员与部门的中间结果表和职务信息表外联合并中间结果表在中间结果表中选择所有性别为女性的行,生成新的中间结果表在中间结果表中选择列职务 ID 为外连接条件SELECT 人员信息表.名称, 部门信息表.部门名称, 职务表.职务名称FROM 人员信息表 ,部门信息表, 职务表WHERE 人员信息表.部门 ID=部门信息表.部门 ID 人员表与部门表进行内连接AND 人员信息表 .职务 ID=职务表.职务 ID(+) 与职务表进行外连接AND 人员信息表.性别=女显性连接 SQL 文步骤一 在(人员信息表)与 (部门信息表)表中执行一个内连接,内连接会将人员表中部门 ID为
22、空的人员信息从中间结果表中过滤掉.步骤一 产生的中间结果表编号 名称 部门 ID 年龄 职务 ID 性别 电话 部门 ID 部门名称122 李晶晶 1 26 1 女 2234555 1 人力资源部123 张金 1 29 女 3322123 运行维护部124 王力 2 35 1 男 2245553 1 运行维护部125 李心 3 21 2 女 3332233 2 财务部步骤二 中间结果表于( 职务信息表) 执行一个外连接,中间结果表为驱动表. 驱动表中即使职务 id 为空,新生成的中间结果表也会这条信息保存下来.步骤二 产生的中间结果表编号 名称 部门 id 年龄 职务 id 性别 电话 部门
23、id 部门名称 职务 id 职务名称122 李晶晶 1 26 1 女 2234555 1 人力资源部 1 职员123 张金 1 29 女 3322123 运行维护部124 王力 2 35 1 男 2245553 1 运行维护部 1 职员125 李心 3 21 2 女 3332233 2 财务部 2 经理步骤三 选择性别为女的所有行生成中间结果表.虽然职务有空值出现,但是通过外联它还是可以不被过滤掉.步骤三 产生的中间结果表122 李晶晶 1 26 1 女 2234555 1 人力资源部 1 职员123 张金 1 29 女 3322123 运行维护部125 李心 3 21 2 女 3332233
24、 2 财务部 2 经理步骤四 选择要显示的列,生成最终中间结果表,将显示给客户端.步骤四 产生的中间结果表名称 部门名称 职务名称李晶晶 人力资源部 职员张金 运行维护部李心 财务部 经理SELECT 人员信息表.名称, 部门信息表.部门名称, 职务表.职务名称FROM 人员信息表 inner join 部门信息表 on 人员信息表.部门 ID=部门信息表.部门 ID left join 职务表 on 职务表.职务 ID=人员信息表 .职务 ID WHERE 人员信息表.性别=女Select 表达式select 表达式也是一种常量,它会对应某种数据类型.如数字,字符串,日期,时间等.这些有自己
25、属性类型的表达式,也叫标量表达式.除了标量表达式之外,还有行表达式和表表达式.行表达式是由一组标量表达式组成的,每个行表达式都有一个或多个标量表达式.有多个或者一个行表达式组成的表达式为表表达式也叫表值.表达式的分类 标量表达式 行表达式 表表达式( 人员工资表)人员名称 基本工资 奖金 罚款 补助张淋淋 1200 750 50 120马越 800 200 10 120李洋 900 350 40 120SELECT 人员名称(标量表达式),基本工资(标量表达式),奖金(标量表达式),补助(标量表达式)FROM 人员工资表Select 关键字选择的列部分就是一个标量表达式.你可以将中间结果表每个
26、列单元格看成为一个标量表达式.-获得结果-人员名称 基本工资 奖金 补助张淋淋 1200 750 120马越 800 200 120李洋 900 350 120由多个标量表达式组成的一行数组,为行表达式张淋淋 1200 750 120这 4 个标量表达式组成了一个行表达式由一个或多个行表达式构成了表表达式张淋淋 1200 750 120马越 800 200 120李洋 900 350 120我们对行表达式和表表达式也可以叫做复合行表达式.多个行表达式组成每个行中的列单元就是一个标量表达式标量表达式操作标量表达式就是 select 关键字后面的列要表达的信息部分.如果 2 个标量表达式类型相同可
27、以进行运算,合并或者拼接成字符串.如果标量表达式类型不一样,也可以将它们拼接成字符串.注意 select 后面的列不可以出现复合行(行表达式,表表达式)例 给出所有人员名称和他们当月工资总合.SQL 文步骤一 from 关键字将人员工资表中的信息,取到一个中间结果表中.步骤一 产生的中间结果表人员名称 基本工资 奖金 罚款 补助张淋淋 1200 750 50 120马越 800 200 10 120李洋 900 350 40 120步骤二 SELECT 关键字表示了我们要生成一个有人员名称和基本工资列+奖金列+补助列总和为一列的最终结果表.首先数据库会把中间结果表中的每个行表达式中基本工资列上
28、的数据,奖金列上的数据,补助列上的数据进行相加.把相加的结果放在一个新列中.生成一个新的中间结果表。 步骤二 产生的中间结果表人员名称 基本工资 奖金 补助 产生的新列张淋淋 1200 750 120 2070马越 800 200 120 1120李洋 900 350 120 1370步骤三 在新的中间结果表中抽取人员名称列和新产生的列为最终结果表。发送给客户端。-获得结果-人员名称 (基本工资+奖金+ 补助)张淋淋 2070马越 1120李洋 1370大家可以清楚的明白了每个行中的标量表达式之间是可以进行运算的。也可以通过 SELECT3 个列相加的和等于新列的值SELECT 人员名称 ,(
29、基本工作+奖金+补助) 三个标量表达式相加计算生成一个新的标量表达式FROM 人员工资表关键字中间结果表中的行表达式中创建新的列。例 给出人员名称和他们当月工资总合(减去罚款金额),将它们生成在一个新列中表示.步骤一 from 关键字将人员工资表中的信息,取道一个中间结果表中.步骤一 产生的中间结果表人员名称 基本工资 奖金 罚款 补助张淋淋 1200 750 50 120马越 800 200 10 120李洋 900 350 40 120步骤二 通过 SELECT 关键字,中间结果表中的每行上面的(基本工作列+奖金列+补助列)-罚款列生成一个总和数。人员名称列上的数据要和新生成的总和数据合并
30、成一个新列(新的标量表达式) ,直接合并是不可以的,因为 2 个列的属性(也叫常量)是不一样的 。我们要使用(人员名称|新列)方法来合并它,因为 |会将两边的表量表达式默认成为字符串类型。2 个字符串类型的表量表达式可以合并成一个新的表量表达式。步骤二 产生的中间结果表人员名称 基本工资 奖金 罚款 补助 产生的新列张淋淋 1200 750 50 120 张淋淋 2020马越 800 200 10 120 马越 1110李洋 900 350 40 120 李洋 1330步骤三 在新的中间结果表中抽取新产生的列为最终结果表。发送给客户端-获得结果-人员名称|张淋淋 2020马越 1110李洋 1
31、330现在我们只展示了标量表达式的列合并和列运算过程,它的作用范围就在行表达式中.人员名称与运算结果合并运算出工资结果SELECT 人员名称 |(基本工作 +奖金+补助)-罚款 (使用|可以 将 2 个标量表达式合并成一个字符串属性的表量表达式)FROM 人员工资表在 SQL 最终结果表中只支持标量表达式现在的 SQL 数据库中最终结果表(最后传到客户端中的表),列单元中只能存放标量表达式.但是在中间结果表列单元中是可以出现复合行(行表达式,表表达式)的.有很多情况我们需要在中间结果表的列中的存放复合行信息.但是这些信息被传到最终结果表会出现异常,不会被识别.所以我们就要使用到聚合函数将中间结
32、果表有复合行的列转换成标量表达式,传给最终结果表.保证最终结果表的列中不会出现复合行,发送给客户端.例 给出所有人员名称和本人工资总合和全体人员的工资总和( 人员工资表)人员名称 基本工资张淋淋 1200马越 800李洋 900步骤一 取得人员工资表中间结果表.步骤一 产生的中间结果表人员名称 基本工资张淋淋 1200马越 800李洋 900步骤二 select 关键字会生成一个新中间结果表,中间结果表中每行都创建出一个新列.新列单元格中装入一个(SELECT 基本工资 FROM 人员工资表)语句生成的表表达式.中间结果表中有几行就要执行几次 SQL(SELECT 基本工资 FROM 人员工资
33、表)语句,每次执行都要走一次SELECT 生成过程.步骤二 产生的中间结果表人员名称 基本工资 新生成列张淋淋 1200马越 800李洋 900步骤三 将中间结果表生成最终结果表,生成过程中数据库执行出现异常列中的数据结构SELECT 人员名称 ,基本工资,(SELECT 基本工资 FROM 人员工资表) 查询所有人的工资总和 (表表达式)FROM 人员工资表工资202011101330工资202011101330 工资202011101330在执行这条 SQL 查询计划时出现错误 ,因为在最终结果表列部分有一个表表达式出现,SQL不支持在传给客户端的最终结果表中有复合行信息出现在列部分.我们
34、为了得到正确的结果,需要将这个复合行(表表达式)转换成为标量表达式,它才能在 SQL 的列中正确执行.SELECT 人员名称 ,(基本工作+奖金+补助)-罚款,(SELECT (基本工作+奖金+补助) - 罚款 FROM 人员工作表) 表表达式不可以出现在列部分 From 人员工作表我们使用 SUM()函数将表表达式中的数据转换成标量表达式,我们这么做的目的就是将表表达式存在的多个数据行数据结构,变成一个数据行和列的数据结构.正确的 SQL步骤一 取得人员工资表中间结果表.步骤一 产生的中间结果表人员名称 基本工资张淋淋 1200马越 800李洋 900步骤二 select 关键字会生成一个新
35、中间结果表,中间结果表中每行都创建出一个新列.新列单元格中装入一个(SELECT 基本工资 FROM 人员工资表)语句生成的表表达式.中间结果表中有几行就要执行几次 SQL(SELECT 基本工资 FROM 人员工资表)语句,每次执行都要执行一次 SELECT 生成过程.通过 SUM 函数将表表达式转换成一个标量表达式.步骤二 产生的中间结果表人员名称 基本工资 新生成列张淋淋 1200 4460马越 800 4460李洋 900 4460表表达式数据工资202011101330SELECT 人员名称 ,(基本工作+奖金+补助)-罚款, (SELECT SUM(基本工作+奖金+补助) - 罚款
36、) FROM 人员工作表) 将表表达式转换成标量表 达式FROM 人员工资表工资202011101330SUM() 函数 所有人工资总和4460SUM 函数将表表达式合并成标量表达式工资202011101330步骤三 将中间结果表生成最终结果表,传给客户端.-获得结果-人员名称 工资 所有人工资总和张淋淋 2070 4460马越 1120 4460李洋 1370 4460通过上面的介绍我们现在知道了在 SQL 查询计划中 SELECT 列部分只能以标量表达式的形式传送给客户端.如果有复合行情况出现,我们要使用函数或者其他手段将它变成一个标量表达式.不同标量表达式都有自己的属性,相同属性的标量表
37、达式可以进行运算或者合并.表达式常量类型 数字常量 字符串常量 日期常量 时间常量时戳常量 布尔常量 十六进制常量不同数据库为处理结果表中列的标量表达式都提供了功能强大的函数,这些函数如何的使用和学习不在本次学习的范围.表表达式与子查询我们已提及每个表表达式的值都是有一组行构成.如果我们将表表达式放入到 From 中在又from 生成一个表表达式.而这个重新生成的过程叫做子查询.(人员信息表)编号 名称 部门 职务 年龄 性别 电话122 李晶晶 人力 职员 26 女 2234555123 张金 人力 职员 29 男 3322123124 王力 机材 经理 35 男 2245553125 李心
38、 机材 职员 21 女 3332233例 给出年龄小于 30 的女性人员名称.SELECT 人员表 1.人员名称 FROM ( select 名称,性别 生成一个年龄小于 30 中间结果表(表表达式)From 人员信息表 Where 年龄4000 判断那些分组后的行复合条件步骤一 ,二 产生的结果同上步骤三 使用 HAVING 关键字判断每行工资金额列所有数据相加的总和是否大于 4000,如果大于 4000 的就放入到一个新的中间表中.步骤三 判断过程名称 日期 工资金额 SUM 函数2012-08 12602012-09 11602012-10 1230张淋淋2012-11 1170SUM(
39、工资金额) = 4820 判断它是否大于 4000 2012-09 14002012-10 1470李洋2012-11 1305SUM(工资金额) = 4175 判断它是否大于 40002012-09 13502012-10 1320王晓林2012-11 1300SUM(工资金额) = 3970 判断它是否大于 4000步骤三 产生的中间结果表结构名称 日期 工资金额2012-08 12602012-09 11602012-10 1230张淋淋2012-11 11702012-09 14002012-10 1470李洋2012-11 1305步骤四 通过 SELECT 关键字将中间结果表中的名
40、称列中的数据拿到一个新的中间结果表中,通过 SUM 函数生成一个新列,这个新列里的数据就是每行中工资金额列上的数据总和.在把这个新列放到新的中间结果表中.步骤四 中间结果表创建新列过程名称 日期 工资金额 SUM 函数 新列2012-08 12602012-09 11602012-10 1230张淋淋2012-11 1170工资列相加 48202012-09 14002012-10 1470李洋2012-11 1305工资列相加 4175步骤四 中间结果表结构名称 新列张淋淋 4820李洋 4175步骤五 将最终结果表传给客户端.通过上面的例子大家可以看到了 HAVING 一定要在 group
41、 by 分组后使用,主要的作用就是判断分组后产生的复合行。HAVING 嵌套判断(工资表)名称 部门 工资金额张淋淋 人力 1100王媛媛 人力 1160李冶 人力 1230赵淑 人力 1170方芳 财务 1400李静 财务 1470张萍 财务 1305王晓林 部门 1 1570王彤 部门 1 1200例 给出每个部门大于部门平均工资的人员名字,部门,工资金额。那么通过我们现在的知识来解决这个问题。SQL 文Select * From 工资表 工资表别名 Where exists(Select * From 工资表 where 工资表.部门=工资表别名. 部门Group by 工资表.部门Ha
42、ving avg(工资表.工资金额) 工资表别名.工资金额)可以将工资表中的每行部门列,工资金额列上的数据,成为EXISTS 函数生成新表的条件。步骤一 通过 FROM 产生一个中间结果表。为了不让数据库和我们将要生成了别一个中间结果表发生混乱我们给这个中间结果表起一个别名,别名名称为工资表别名步骤一 产生的中间结果表名称 部门 工资金额张淋淋 人力 1100王媛媛 人力 1160李冶 人力 1230赵淑 人力 1170方芳 财务 1400李静 财务 1470张萍 财务 1305王晓林 部门 1 1570王彤 部门 1 1200步骤二 将(工资表别名)中间结果表每行的部门列上的部门信息和工资金
43、额列上的工资金额为条件传给 WHERE 关键字中 EXISTS 函数要执行的 SQL 查询语句中,作为查询判断条件。在 EXISTS 函数中如果有符合条件的中间结果表生成,那么这行数据就放入一个新的中间结构表中。中间结果表每行都会执行如下过程张淋淋 人力 1100select * from 工资表where 工资表.部门= 人力 行中的部门名称为嵌套语句的部门条件group by 工资表.部门 having avg(工资表. 工资金额) 1100 行中的工资金额为嵌套语句的比较平均工作的表件1 FROM 将工资表装入一个中间表中。2 where 将部门为人力的行装入一个中间结果表中(它的条件是
44、上个别名表传入的) 。3 group by 在将 2 的中间结果表分组以部门为条件,生成一个有复合行的中间结果表。3 having 将传入的工资金额与中间结果表每行的工资金额列通过平均函数生成的数据进行比较。有符合条件的就加入到一个新的中间结果表中。4 SELECT 将中间表所有列都放入最终结果表。5 将这个表表达式反给 EXISTS 函数,如果表表达式不为空就说话别名表这行数据符合条件。步骤二 产生的中间结果表李冶 人力 1230赵淑 人力 1170方芳 财务 1400李静 财务 1470王晓林 部门 1 1570步骤三 SELECT 关键字选择所有列,在生成一个最终结果表。步骤三产生的中间
45、结果表李冶 人力 1230赵淑 人力 1170方芳 财务 1400李静 财务 1470王晓林 部门 1 1570步骤四 将信息发送给客户端。行转列介绍在很多时候会有一些行转列方面的业务需求。例如(工资表)名称 月份 工资金额张淋淋 1 1200张淋淋 2 1210张淋淋 3 1220张淋淋 4 1230张淋淋 5 1240李静 1 1110李静 2 1120李静 3 1130李静 4 1140我们需要通过 SQL 查询出一个这样的结果表业务。名称 1 2 3 4 5张淋淋 1200 1210 1220 1230 1240李静 1110 1120 1130 1140步骤一 通过 FROM 产生一
46、个中间结果表。名称 月份 工资金额张淋淋 1 1200张淋淋 2 1210张淋淋 3 1220张淋淋 4 1230张淋淋 5 1240李静 1 1110李静 2 1120李静 3 1130李静 4 1140步骤二 GROUP BY 以名称为分组条件。得到一个新的中间结果表名称 月份 工资金额1 12002 12103 12204 1230张淋淋5 12401 11102 11203 1130李静4 1140步骤三 我们通过 SELECT 关键字在新的中间结果表中增加 5 个新列,每个列上的数据都是通过判断函数 decode,判断指定条件得到的数据。判断月份,如果复合行中的月份与判断条件相同,数
47、据库会将与这个月份所对应的工资金额拿出来.将它放到新列,新列有可能出现复合行所有我们也需要一个 sum 聚合函数来把这个列合并成一个标量表达式中间表创建过程。名称 月份 工资金额 1 2 1 12002 12103 12204 1230张淋淋5 1240Decode(月份,1,工资金额)如果月份列等于 1,就把于 1 月份对应的工资金额信息拿到新列中 在 sum 聚合成一个标量Decode(月份,2,工资金额)如果月份列等于 2,就把于 2 月份对应的工资金额信息拿到新列中 在 sum 聚合成一个标量1 11102 11203 1130李静4 1140Decode(月份,1,工资金额)如果月份
48、列等于 1,就把于 1 月份对应的工资金额信息拿到新列中 在 sum 聚合成一个标量Decode(月份,2,工资金额)如果月份列等于 2,就把于 2 月份对应的工资金额信息拿到新列中 在 sum 聚合成一个标量步骤三 中间结果表名称 1 2 3 4 5张淋淋 1200 1210 1220 1230 1240李静 1110 1120 1130 1140步骤四 将中间结果表信息,发送给客户端。SQL 文Select 名称,sum(Decode(月份,1,工资金额)) ,sum(Decode(月份,2,工资金额)),sum(Decode(月份,3,工资金额)), sum(Decode(月份,4,工资金额)), sum(Decode(月份,5,工资金额))From 工资表Group by 名称