编写SQL语句,查询职员表(emp表),逐一完成如下功能:
1)查询emp表中的入职日期列(hiredate),并按照时间的先后顺序列出;
2)查询工资大于1600的员工姓名和工资;
3)查询员工号为7369的员工的姓名和部门编码;
4)查询工资不在4000到5000之间的员工的姓名和工资;
5)查询那些尚未分配部门的员工的姓名;
6)已知员工的每月收入为:薪资+绩效*0.8,如果绩效为null,则表示绩效为 0。查询员工的姓名以及月收入(列名为money),并按照月收入升序排列。查询效果如图-1所示。
图-1
实现此案例需要按照如下步骤进行。
步骤一:查询入职日期列
emp表中,有hiredate列表示入职日期,查询该列,并使用order by子句进行升序排列。SQL语句如下所示:
selecthiredate from emp order by hiredate;
步骤二:查询工资大于1600的员工姓名和工资
emp表中,ename列表示员工姓名,sal列表示工资,查询这两列,并使用where子句对工资进行判断。SQL语句如下所示:
select ename, sal from emp where sal > 1600;
步骤三:查询员工号为7369的员工的姓名和部门编码
emp表中,empno列表示员工编号,ename列表示员工姓名,deptno列表示部门编码,查询ename和deptno列,并使用where子句对员工编号进行判断。SQL语句如下所示:
select ename, deptno from emp where empno = 7369;
步骤四:查询工资不在4000到5000之间的员工的姓名和工资
需要使用notbetween…and…子句对工资进行范围的判断。SQL语句如下所示:
select ename, sal from emp where sal not between 4000 and 5000;
步骤五:查询那些尚未分配部门的员工的姓名
如果某条数据的deptno列为null,则表示该员工没有分配部门。因此,需要使用is null 判断 deptno 列是否为空。SQL语句如下所示:
select ename from emp where deptno is null;
步骤六:查询员工的月收入
emp 表中,comm 列表示绩效,该列可能为 null。因此,首先需要使用 nvl 函数对comm 列进行转换:如果comm 列为 null,则转换为数值 0;然后,使用计算表达式 sal + nvl(comm,0) * 0.8计算月收入。
计算完月收入后,使用 order by 子句进行排序。SQL语句如下所示:
select ename, sal + nvl(comm,0) * 0.8 money from emp order by money;
1)查询各职位的员工工资的最大值,最小值,平均值以及总和,查询结果如图-2所示:
图-2
2)查询各职位的员工人数,查询结果如图-3所示:
图-3
3)查询员工的最高工资和最低工资的差距,并显示列名为DIFFERENCE,查询结果如图-4所示:
图-4
4)查询各个管理者属下员工的最低工资,其中最低工资不能低于800,且没有管理者的员工不计算在内。查询结果如图-5所示:
图-5
5)查询各个部门中工资大于1500的员工人数,查询结果如图-6所示:
图-6
6)查询各部门的平均绩效,如果绩效为null,则按数值0进行统计,查询结果如图-7所示:
图-7
聚合函数用于对数据进行统计,用于统计全表的数据,也可以将表的全部数据划分为几组数据,每组数据统计出一个结果。因为是多行数据参与运算返回一行结果,也称作分组函数、多行函数、集合函数。
常见的聚合函数有:
注意:聚合函数忽略NULL值。
使用聚合函数进行数据统计时,往往结合GOURP BY 子句使用。GOURP BY 子句实现按什么分组。
HAVING子句用来对分组后的结果进一步限制,比如按部门分组后,得到每个部门的最高薪水,可以继续限制输出结果。需要注意的是,HAVING 子句必须跟在GROUP BY后面,不能单独存在。
实现此案例需要按照如下步骤进行。
步骤一:查询各职位的员工工资的最大值,最小值,平均值以及总和
emp 表中,有sal列表示工资,job 列表示职位。因此,需要对 job 列进行分组,统计 sal 列的最大值、最小值、平均值以及总和即可。SQL语句如下所示:
select job, max(sal), min(sal), avg(sal), sum(sal) from emp group by job;
步骤二:查询各职位的员工人数
emp 表中,job 列表示职位。因此,需要对 job 列进行分组,统计各组中记录的条数即可。SQL语句如下所示:
select job, count(*) from emp group by job;
步骤三:查询员工的最高工资和最低工资的差距,并显示列名为DIFFERENCE
实现此案例,需要分别使用 MAX 和 MIN 函数查询员工的最高工资和最低工资,并求差值。SQL语句如下所示:
select max(sal)-min(sal) "DIFFERENCE"from emp;
步骤四:查询各个管理者属下员工的最低工资,其中最低工资不能低于800,且没有管理者的员工不计算在内
emp 表中,有 mgr 列表示员工的管理者,因此,首先需要对 mgr 列进行分组,并统计每组中 sal 列的最小值。
这样,会统计出每个管理者下属员工的最低工资,为了达到案例的要求,还需要判断 mgr 列不为空,以及最低工资不低于 800。
SQL语句如下所示:
select mgr, min(sal)from emp where mgr is not null group by mgr having min(sal) >= 800;
步骤五:查询各个部门中工资大于1500的员工人数
emp 表中,有 deptno 列表示员工的所属部门,因此,需要对 deptno 列进行分组,并统计各组中记录的条数。
为了只统计工资大于 1500 的记录数,需要使用where子句进行过滤。SQL语句如下所示:
select deptno , count(*) from emp where sal > 1500 group by deptno;
步骤六:查询各部门的平均绩效,如果绩效为null,则按数值0进行统计
emp表中,有 deptno 列表示员工的所属部门,comm 列表示绩效。因此,首先需要对 deptno 列进行分组,并统计 comm 列的平均值。
但是,因为 comm 列可能为 null,而聚合函数会忽略 null值。因此,需要使用 NVL 函数对 null 值进行处理。SQL语句如下所示:
SELECT deptno, AVG(NVL(comm,0)) avg_comm FROM emp group by deptno;
1)查询员工的姓名及其所在部门的名字和城市,如图-8所示:
图-8
2)查询员工的姓名和他的管理者的姓名,查询结果如图-9所示:
图-9
3)查询员工的编号、姓名、部门编码、部门名称以及部门所在城市。要求:把没有部门的员工也查出来,查询结果如图-10所示:
图-10
4)查询员工的信息及其所在部门的信息。要求:把没有员工的部门也查出来,查询结果如图-11所示:
图-11
5)查询员工的信息及其所在部门的信息。要求:只查询没有员工的部门,查询结果如图-12所示:
图-12
6)查询并显示SALES部门的职位,查询结果如图-13所示:
图-13
7)查询所有部门的名称、所在地、员工数量以及平均工资,查询结果如图-14所示:
图-14
8)执行下面两条查询语句,并比较查询结果。
SELECT e1.ename, e2.ename FROM emp e1, emp e2WHERE e1.mgr = e2.empno
SELECT e1.ename, e2.enameFROM emp e1, emp e2WHERE e1.empno = e2.mgr
查询两个或两个以上数据表或视图的查询叫做连接查询。连接查询分为:
实现此案例需要按照如下步骤进行。
步骤一:查询员工的姓名及其所在部门的名字和城市
emp表中,有deptno列表示员工所在部门的编码;dept表中,也有deptno列表示部门编码,因此,可以通过此列对两个表进行关联查询。SQL语句如下所示:
select ename , dname , loc from emp e join dept d on e.deptno = d.deptno ;
步骤二:查询员工的姓名和他的管理者的姓名
emp表中,有mgr列记载员工的管理者,而管理者同时也在emp表中。因此,需要使用自连接进行查询。SQL语句如下所示:
select t1.ename , t2.ename mgr_name from emp t1 join emp t2 on t1.mgr = t2.empno ;
步骤三:查询员工的编号、姓名、部门编码、部门名称以及部门所在城市(把没有部门的员工也查出来)
emp表中,有deptno列表示员工所在部门的编码;dept表中,也有deptno列表示部门编码,因此,可以通过此列对两个表进行关联查询。因为要求把没有部门的员工也查出来,则需要将emp表中的所有数据都列出来,需要使用emp表左外连接dept表。
SQL语句如下所示:
select e.empno , ename , d.deptno , d.dname , d.loc from emp e left outer join dept d on e.deptno = d.deptno ;
步骤四:查询员工的信息及其所在部门的信息(把没有员工的部门也查出来)
要求把没有员工的部门也查出来,则需要将dept表中的所有数据都列出来,需要使用dept表左外连接emp表,或者使用emp表右外连接dept表。
SQL语句如下所示:
select e.empno , e.ename , d.deptno , d.dname , d.loc from dept d left outer join emp e on e.deptno = d.deptno;
步骤五:查询员工的信息及其所在部门的信息(只查询没有员工的部门)
实现此案例,只需要在上一个案例的基础上,添加过滤条件:员工编号为null。
SQL语句如下所示:
select e.empno , e.ename , d.deptno , d.dname , d.loc from dept d left outer join emp e on e.deptno = d.deptno where e.empno is null ;
步骤六:查询并显示SALES部门的职位
emp表中,有job列表示职位,deptno列表示部门编号,而部门名称(如 SALES)信息存储在dept表中。因此,需要通过 deptno列对两个表进行关联查询,并根据部门的名称进行过滤。
SQL语句如下所示:
select distinct e.job from emp e, dept d where e.deptno = d.deptno and d.dname = 'SALES';
步骤七:查询所有部门的名称、所在地、员工数量以及平均工资
首先,统计emp表各部门的员工数量以及平均工资:需要对 deptno 列进行分组,并统计sal列的平均值和记录数;
其次,将上一步中的查询结果作为中间表,与dept表,进行关联查询,查询部门的名称、所在地以及上一步中的统计结果。
SQL语句如下所示:
select d.dname, d.loc, e.EMP_COUNT, e.SAL_AVG from dept d join( select deptno, count(*) as "EMP_COUNT", avg(sal) as "SAL_AVG" from emp group by deptno ) e on d.deptno = e.deptno;
步骤八:执行下面两条查询语句,并比较查询结果
分析第一条查询语句:
SELECT e1.ename, e2.ename FROM emp e1, emp e2WHERE e1.mgr = e2.empno
此语句中:查询e1表中的员工姓名,以及e1中员工的管理员的姓名。查询的过程如图-15所示(以MGR列中的数据7902和7698为例):
图-15
由图-15可以看出,SMITH的管理者为FORD,而ALLEN和WARD拥有相同的管理者:BLAKE。
因此,第一条语句的作用在于:查询每名员工的姓名及其管理者的姓名,查询结果如图-16所示:
图-16
继续分析第二条查询语句:
SELECT e1.ename, e2.ename FROM emp e1, emp e2WHERE e1.empno = e2.mgr
此语句中:查询e1表中的员工姓名,以及e1中员工的下属的姓名。查询的过程如图-17所示(以empno值为7566的数据为例):
图-17
由图-17可以看出,JONES有两名下属:SCOTT和FORD。
因此,第二条语句的作用在于:查询每个管理者姓名及其下属员工的姓名,查询结果如图-18所示:
图-18