准备三张表,分别是员工表(emp)、部门表(dept)和工资等级表(salgrade),后续所要进行的查询操作都将以这三张表作为数据源,包括基本查询和复合查询。
员工表(emp)中包含如下字段:
员工表的表结构及表内数据:
部门表(dept)中包含如下字段:
部门表的结构和表内数据:
工资等级表(salgrade)中包含如下字段:
工资等级表的结构和表内数据:
示例1: 查询工资高于500或岗位为MANAGER的雇员,同时还要满足他们的姓名首字母为大写的J。
示例2: 按照部门号升序而雇员的工资降序排序。
示例3: 使用年薪进行降序排序。
示例4: 显示工资最高的员工的名字和工作岗位。
除了上面的方式外,还可以使用子查询的方式:
示例5: 显示工资高于平均工资的员工信息。
示例6: 显示每个部门的平均工资和最高工资。
将每个部门分为一个组进行聚合统计最高工资和平均工资。
示例7: 显示平均工资低于2000的部门号和它的平均工资。
分组查询每个部门的平均工资筛选出平均工资小于2000的。
示例8: 显示每种岗位的雇员总数,平均工资。
分组查询岗位的雇员总数,平均工资。
实际开发中往往数据来自不同的表,所以需要多表查询。
我们来看以下示例:
示例1: 显示雇员名、雇员工资以及所在部门的名字。
因为上面的数据来自员工和部门表,因此要多表联合查询。
首先,我们先查看两个表中的数据:
然后,我们尝试查询时带上这两个表:
以姓名为SMITH的数据为例观察:
我们可以发现在两张表联合查询得到的结果中,表中姓名为SMITH的数据是由emp表中姓名为SMITH的数据与dept表中的所有数据结合得来的。此外两张表联合查询得到的结果中所有数据都是这样得来的。这本质是将两个表中的数据进行穷举组合的结果,这个穷举组合的过程也叫做笛卡尔积。
由两张表联合查询得到的结果可以看作一张新表,我们对这张新表加上约束条件,比如只保留emp表中deptno等于dept表中deptno的数据,得到的结果就是将emp中对应的数据与dept表中对应数据结合的表。
仍以姓名为SMITH的数据为例观察:
得到的结果是SMITH在emp表中的信息和对应的部门名和部门地点的表。
我们用这种方式来显示雇员名、雇员工资以及所在部门的名字:
示例2: 显示部门号为10的部门名,员工名和工资。
示例3: 显示各个员工的姓名,工资,及工资级别。
姓名,工资在emp中而工资级别在salgrade表中,因此需要将两个表联合查询,然后由于每个工资级别的工资范围不一样,因此采用emp表中员工在某个工资范围作为筛选条件,可以得到对应员工工资,对应工资等级的结果。
首先,两张表直接联合查询的结果:
然后,对两个表联合查询的结果进行筛选,筛选出工资符合自身等级的:
自连接是指在同一张表连接查询。
自连接将一张表和自己进行笛卡儿积运算。
自连接需要在from中对表重命名。
from的重命名SQL语句的后续操作都能使用。
将salgrade表自连接:
示例: 显示员工FORD的上级领导的编号和姓名(mgr是员工领导的编号–empno)。
首先将emp表进行自连接,也就是将emp表和emp表进行笛卡尔积运算:
在自连接时,将表分别重命名为了e1,e2,当e1表中的某人的编号等于e2表中FORD领导的编号,即是我们想要的数据:
子查询是指嵌入在其他sql语句中的select语句,也叫嵌套查询。
返回一行记录的子查询。
示例: 显示SMITH同一部门的员工。
查询SMITH员工的部门号作为条件筛选员工。
返回多行记录的子查询。
示例: 查询和10号部门的工作岗位相同的雇员的名字,岗位,工资,部门号,但是不包含10自己的。
首先,查看10号部门的工作岗位表:
然后,查找人员中筛选出工作岗位在10号部门的工作岗位表中的,然后去除部门号为10的人员:
示例: 显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号。
首先,查看部门30的所有员工的工资表:
然后,查询比部门30的所有员工的工资表中工资都高的的员工的姓名、工资和部门号:
示例: 显示工资比部门30的任意员工的工资高的员工的姓名、工资和部门号(包含自己部门 的员工)。
首先,查看部门30的所有员工的工资表:
然后,查询比部门30的所有员工的工资表中任意一个员工工资高的的员工的姓名、工资和部门号:
多列子查询则是指查询返回多个列数据的子查询语句。
多列子查询在比较多列数据时需要将待比较的多个列用圆括号括起来。
多列子查询同样能使用in,all,any关键字。
示例: 查询和SMITH的部门和岗位完全相同的所有雇员,不含SMITH本人。
查询SIMTH的部门和工作岗位,在emp表中寻找和其相同的,然后去除SIMTH:
将上面的=换成in就变成了多行多列子查询:
子查询语句出现在from子句中。
示例1: 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资。
查看各部门的平均工资表:
然后,将员工表和各部门的各部门的平均工资表进行笛卡尔积运算:
最后,将员工表和各部门的平均工资表进行笛卡尔积运算后的结果筛选出部门号相同并且工资高于平均工资,显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资。:
示例2: 显示每个高于自己部门平均工资的员工的姓名、部门、工资、平均工资、部门工作位置。
该示例是在上一个示例中加了显示部门工作位置的条件,因此还需要和部门表进行联合查询,然后筛选出部门号相同的:
示例3: 查找每个部门工资最高的人的姓名、工资、部门、最高工资。
首先,查看各部门最高工资表:
然后,查看员工表和各部门最高工资表进行的笛卡尔积运算:
最后,将员工表和各部门最高工资表进行的笛卡尔积运算得到的结果进行条件筛选,筛选的条件是部门号相同,工资相同,显示每个部门工资最高的人的姓名、工资、部门、最高工资:
示例4: 显示每个部门的信息(部门名,编号,地址)和人员数量。
方式1: 使用子查询多表。
首先查看各组人数表:
然后将各组人数表和部门表进行笛卡尔积运算,然后筛选出各组人数表和部门表中部门号相同的:
方式2: 直接多表联合查询并且分组筛选。
首先,查看职员表和员工表笛卡尔积的结果:
然后,对部门表和员工表笛卡尔积的结果进行筛选,筛选出部门编号相同的:
然后将对部门表和员工表笛卡尔积的结果,筛选出部门编号相同的表按部门表的名字、部门号、工作地点进行分组,然后显示出每个部门的信息(部门名,编号,地址)和人员数量,其中按部门表的名字、部门号、工作地点三种属性分组只是因为只有group by中的属性才能显示。
为了合并多个select的执行结果,可以使用集合操作符 union,union all。
union操作符:
该操作符用于取得两个结果集的并集。当使用该操作符时,会自动去掉结果集中的重复行。
union all操作符:
该操作符用于取得两个结果集的并集。当使用该操作符时,不会去掉结果集中的重复行。
示例: 将工资大于2500或职位是MANAGER的人找出来。
首先,查看工资大于2500的人员表和职位是MANAGER的人员表:
然后,分别用union和union all操作符合并大于2500的人员表和职位是MANAGER的人员表:
合并的两个表,列属性相同并且列个数相同,属性列顺序不同: