本人菜鸡,如有错误,恳请指出。
Notes
聚合函数(组函数):用来输入多个数据,输出一个数据的,如sum,min,max,avg,count
为什么where不能跟聚合函数?
聚集函数也叫列函数,它们都是基于整列数据进行计算的,而where子句则是对数据行进行过滤的(这里过滤是在一个记录里边过滤的,基于"行"),在筛选过程中依赖“基于已经筛选完毕的数据得出的计算结果”是一种悖论,这是行不通的。更简单地说,因为聚集函数要对全列数据时行计算,因而使用它的前提是:结果集已经确定!
所有包含于SELECT 列表中,而未包含于组函数中的列都必须包含于 GROUP BY 子句中。
where子句在查询过程中执行优先级别优先于聚合语句
1.WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。
2.GROUP BY 子句用来分组 WHERE 子句的输出。
3.HAVING 子句用来从分组的结果中筛选行。
case
order by
group by 传送门(点我)
having
员工表(emp) | ||
---|---|---|
字段 | 类型 | 描述 |
empno | number(4) | 员工编号 |
ename | varchar2(10) | 员工姓名 |
job | varchar2(9) | 员工岗位 |
mgr | number(4) | 经理编号 |
hiredate | Date | 入职时间 |
sal | number(7,2) | 基本工资 |
comm | number(7,2) | 奖金 |
deptno | number(2) | 所属部门编号 |
部门表(dept) | ||
---|---|---|
字段 | 类型 | 描述 |
deptno | number | 部门编号 |
dname | number | 部门名称 |
loc | number | 地址 |
工资等级表(salgrade) | ||
---|---|---|
字段 | 类型 | 描述 |
grade | number | 等级名称 |
losal | number | 此等级的最低工资 |
hisal | number | 此等级的最高工资 |
奖金表(bonus) | ||
---|---|---|
字段 | 类型 | 描述 |
ename | varchar2(10) | 员工姓名 |
job | varchar2(9) | 员工岗位 |
sal | number | 员工工资 |
comm | number | 员工奖金(commission) |
--员工表 create table EMP ( empno NUMBER(4) primary key, ename VARCHAR2(10), job VARCHAR2(9), mgr NUMBER(4), hiredate DATE, sal NUMBER(7,2), comm NUMBER(7,2), deptno NUMBER(2) ); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (1, 'dog', 'code', 7369, to_date('05-06-2018', 'dd-mm-yyyy'), 5000, 5000, 10); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7369, 'SMITH', 'CLERK', 7902, to_date('17-12-1980', 'dd-mm-yyyy'), 800, null, 20); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('20-02-1981', 'dd-mm-yyyy'), 1600, 300, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7521, 'WARD', 'SALESMAN', 7698, to_date('22-02-1981', 'dd-mm-yyyy'), 1250, 500, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7566, 'JONES', 'MANAGER', 7839, to_date('02-04-1981', 'dd-mm-yyyy'), 2975, null, 20); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('28-09-1981', 'dd-mm-yyyy'), 1250, 1400, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7698, 'BLAKE', 'MANAGER', 7839, to_date('01-05-1981', 'dd-mm-yyyy'), 2850, null, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7788, 'SCOTT', 'ANALYST', 7566, to_date('19-04-1987', 'dd-mm-yyyy'), 3000, null, 20); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7839, 'KING', 'PRESIDENT', null, to_date('17-11-1981', 'dd-mm-yyyy'), 5000, null, 10); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7844, 'TURNER', 'SALESMAN', 7698, to_date('08-09-1981', 'dd-mm-yyyy'), 1500, 0, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7876, 'ADAMS', 'CLERK', 7788, to_date('23-05-1987', 'dd-mm-yyyy'), 1100, null, 20); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7900, 'JAMES', 'CLERK', 7698, to_date('03-12-1981', 'dd-mm-yyyy'), 950, null, 30); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7902, 'FORD', 'ANALYST', 7566, to_date('03-12-1981', 'dd-mm-yyyy'), 3000, null, 20); insert into EMP (empno, ename, job, mgr, hiredate, sal, comm, deptno) values (7934, 'MILLER', 'CLERK', 7782, to_date('23-01-1982', 'dd-mm-yyyy'), 1300, null, 10); --部门表 create table DEPT ( deptno NUMBER(2) primary key, dname VARCHAR2(14), loc VARCHAR2(13) ); insert into DEPT (deptno, dname, loc) values (10, '财务', 'NEW YORK'); insert into DEPT (deptno, dname, loc) values (20, '研发', 'DALLAS'); insert into DEPT (deptno, dname, loc) values (30, '销售', 'CHICAGO'); insert into DEPT (deptno, dname, loc) values (40, '运营', 'BOSTON'); --工资等级表 create table SALGRADE ( GRADE NUMBER, LOSAL NUMBER, HISAL NUMBER ); INSERT INTO SALGRADE VALUES (1, 700, 1200); INSERT INTO SALGRADE VALUES (2, 1201, 1400); INSERT INTO SALGRADE VALUES (3, 1401, 2000); INSERT INTO SALGRADE VALUES (4, 2001, 3000); INSERT INTO SALGRADE VALUES (5, 3001, 9999); --奖金表 create table BOUNS ( ENAME VARCHAR2(10), JOB VARCHAR2(9), SAL NUMBER, COMM NUMBER );
(1) 查询每名员工的empno,ename,sal和dept,要求使用CASE 表达式将各部门由部门号转换为对应的中文名称:10—财务部,20—研发部,30—销售部
SELECT empno,ename,sal, CASE deptno WHEN 10 THEN '财务部' WHEN 20 THEN '研发部' WHEN 30 THEN '销售部' END "部门" FROM "EMP";
(2)使用子查询创建表,并将新表中的记录查询出来
CREATE TABLE emp10 AS SELECT * FROM emp WHERE deptno=10; SELECT * FROM emp10;
(3)统计平均工资大于 500 的部门,显示部门号和平均工资
SELECT deptno "部门号",AVG(nvl(sal,0)+nvl(comm,0)) "平均工资" FROM emp GROUP BY deptno HAVING AVG(nvl(sal,0)+nvl(comm,0))>500;
(4)查找部门 30 中得到最多奖金的员工姓名
SELECT ename "员工姓名" FROM "EMP" WHERE comm=( SELECT MAX(nvl(comm,0)) FROM "EMP" GROUP BY deptno HAVING deptno = 30 );
(5)查找工资大于自己部门平均工资的员工信息
SELECT * FROM emp e WHERE nvl(sal,0)> ( SELECT AVG(nvl(sal,0)) FROM "EMP" GROUP BY deptno HAVING deptno=e.deptno );
SELECT * FROM emp e WHERE sal > (SELECT AVG(nvl(sal,0)) FROM emp WHERE e.deptno=deptno);
(6)查找平均工资大于 2000 的工作岗位
SELECT job "工作岗位" FROM "EMP" GROUP BY job HAVING AVG(nvl(sal,0))>2000;
(7)分组统计每个部门下,每种职位的平均补贴(没奖金的设为0)和总工资(包括奖金)
提示:因为comm属性有空值,需要用nvl()函数处理comm属性
SELECT deptno "部门号",job "职位",AVG(nvl(comm,0)) "平均补贴",SUM(nvl(sal,0)) "总工资" FROM "EMP" GROUP BY deptno,job;
(8)以工作岗位分组,找出平均工资最高的两种岗位。
提示:排序后在where中指定 rownum < 3;
SELECT * FROM ( SELECT job "工作岗位",AVG(nvl(sal,0)) "平均工资" FROM "EMP" GROUP BY job ORDER BY "平均工资" DESC ) WHERE rownum<3;