- 数据表
- 案例
- 1.每个部门最高薪水人名
- 2.哪些人的薪水在部门平均薪水之上
- 3.取得部门中(所有人的)平均薪水等级
- 4.不准用组函数(MAX),取得最高薪水
- 5.取得平均薪水最高的部门的部门编号
- 6.取得平均薪水最高的部门的部门名称
- 7.求平均薪水的等级最低(高)的部门的部门名称
- 8.取得比普通员工的最高薪水还要高的经理人姓名
- 9.取得薪水最高的前五名员工
- 11.取得最后(也就是最大的日期)入职的5名员工
- 12.取得每个薪水等级有多少员工
- 14.列出所有员工及领导的名字
- 15.列出受雇日期早于其直接上级的所有员工编号、姓名、部门名称
- 16.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
- 17.列出至少有5个员工的所有部门
- 18.列出薪水比“SMITH”多的所有员工信息
- 19.列出所有“CLERK”(办事员)的姓名及其部门名称,部门人数
- 20.列出最低薪水大于1500的各种工作及从事此工作的全部雇员人数
- 21.列出在部门“SALES”<销售部>工作的员工的姓名,假定不知道销售部门的部门编号销售部>
- 22.列出薪金高于公司平均薪金的所有员工,所在部门、上级领导、雇员的工资等级
- 23.列出与“SCOTT”从事相同工作的所有员工及部门名称
- 24.列出薪金等于部门30中员工的薪金的其它员工的姓名和薪金
- 25.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称
- 26.列出在每个部门工作的员工数量、平均工资和平均服务期限
- 27.列出所有员工的姓名、部门名称和工资
- 28.列出所有部门的详细信息和人数
- 29.列出各种工作的最低工资及从事此工作的雇员姓名
- 30.列出各个部门MANAGER的最低薪金
- 31.列出所有员工的年工资,按年薪从低到高排序
- 32.求出员工领导的薪水超过3000的员工名称和领导名称
- 33.求部门名称中带“S”字符的部门员工的工资合计、部门人数
- 34.给任职日期超过30年的员工加薪10%
数据表
部门信息表
- dept
字段名 | 中文描述 | 类型 |
---|---|---|
DEPTNO | 部门编号 | INT(2) |
DNAME | 部门名称 | VARCHAR(14) |
LOC | 位置 | VARCHAR(13) |
员工信息表
-
emp
-
DEPTNO 字段是外键,DEPTNO 的值来源于dept 表的主键,起到了约束的 作用
字段名 | 描述 | 类型 |
---|---|---|
EMPNO | 员工编号 | INT(4) |
ENAME | 员工姓名 | VARCHAR(10) |
JOB | 工作岗位 | VARCHAR(9) |
MGR | 上级经理 | INT(4) |
HIREDATE | 入职日期 | DATE |
SAL | 薪水 | DOUBLE(7,2) |
COMM | 津贴 | DOUBLE(7,2) |
DEPTNO | 部门编号(外键) | INT(2) |
薪水等级表
- salgrade
字段名 | 描述 | 类型 |
---|---|---|
GRADE | 等级 | INT |
LOSAL | 最低薪水 | INT |
HISAL | 最高薪水 | INT |
案例
1.每个部门最高薪水人名
- (1)取得每个部门的最高薪水,按照部门分组求最大值
SELECT DEPTNO ,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO;
- (2)把上面的查询结果当做一个临时表T,和EMP表进行连接查询,连接的条件(E.DEPTNO = T.DEPTNO AND E.SAL = T.MAXSAL)
SELECT T.DEPTNO,T.MAXSAL ,E.EMPNO,E.ENAME
FROM EMP E
INNER JOIN (SELECT DEPTNO ,MAX(SAL) MAXSAL
FROM EMP
GROUP BY DEPTNO) T ON (E.DEPTNO = T.DEPTNO AND T.MAXSAL = E.SAL)
ORDER BY T.DEPTNO;
- (3)校验查询结果
SELECT *
FROM EMP
ORDER BY DEPTNO ASC,SAL DESC;
2.哪些人的薪水在部门平均薪水之上
- (1)按照部门编号分组,查询平均薪水
SELECT DEPTNO,AVG(SAL) AVGSAL
FROM EMP E
GROUP BY DEPTNO ;
- (2)把上面的查询结果当做一个临时表T,和EMP表进行连接查询,连接的条件(E.DEPTNO = T.DEPTNO AND E.SAL > T.MAXSAL)
SELECT E.EMPNO,E.ENAME,E.SAL, T.AVGSAL,T.DEPTNO
FROM EMP E
INNER JOIN (SELECT DEPTNO,AVG(SAL) AVGSAL
FROM EMP E
GROUP BY DEPTNO) T ON (E.DEPTNO = T.DEPTNO AND E.SAL > T.AVGSAL)
ORDER BY T.DEPTNO;
3.取得部门中(所有人的)平均薪水等级
- (1)按照部门编号分组,查询平均工资
SELECT DEPTNO,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO ;
- (2)把上面的查询结果当做一个临时表T,和SALGRADE表进行连接,连接的条件(T.AVGSAL BETWEEN S.LOSAL AND S.HISAL)
SELECT T.DEPTNO,T.AVGSAL ,S.GRADE,S.LOSAL,S.HISAL
FROM SALGRADE S
JOIN (SELECT DEPTNO,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO) T ON (T.AVGSAL BETWEEN S.LOSAL AND S.HISAL)
ORDER BY T.DEPTNO;
4.不准用组函数(MAX),取得最高薪水
- 方式1:按照SAL降序排列,使用LIMIT取得第一条结果
SELECT SAL FROM EMP ORDER BY SAL DESC LIMIT 1;
SELECT SAL FROM EMP ORDER BY SAL DESC LIMIT 0,1;
- 方式2:
- (1)使用连接,查询比最高工资低的工资
SELECT DISTINCT A.SAL
FROM EMP A
INNER JOIN EMP B ON (A.SAL < B.SAL);
- (2)把上面的查询结果当做条件,
SELECT SAL
FROM EMP
WHERE SAL NOT IN ( SELECT DISTINCT A.SAL
FROM EMP A
INNER JOIN EMP B ON (A.SAL < B.SAL));
- (3)使用MAX()函数
SELECT MAX(SAL) MAXSAL FROM EMP;
5.取得平均薪水最高的部门的部门编号
- 方式1:按照部分编号分组,查询平均工资,然后按照平均薪水降序排列,使用LIMIT取得第一条结果
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
ORDER BY AVGSAL DESC
LIMIT 1;
- 方式2:
-- (1)按照部分编号分组,查询平均工资
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO;
-- (2)把上面的查询结果当做一个临时表t,查询最高的平均工资
SELECT MAX(T.AVGSAL) FROM ( SELECT DEPTNO ,AVG(SAL) AVGSAL FROM EMP GROUP BY DEPTNO) T;
-- (3)用第二步的查询结果当做条件,过滤第一步的查询结果
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
HAVING AVGSAL = (SELECT MAX(T.AVGSAL)
FROM ( SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO) T);
- 方式3:
-- (1)按照部分编号分组,查询平均工资
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO;
-- (2) 使用LIMIT查询最高的平均工资,也就是查询部门的平均工资,然后按照平均工资降序排列,使用LIMIT取得第一个结果
SELECT AVG(SAL) AVGSAL FROM EMP GROUP BY DEPTNO ORDER BY AVGSAL DESC LIMIT 1
-- (3)把第二步的查询结果当做查询条件,过滤第一步的查询结果
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
HAVING AVGSAL = ( SELECT AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
ORDER BY AVGSAL DESC
LIMIT 1);
6.取得平均薪水最高的部门的部门名称
- 方式1:
-- (1)取得平均薪水最高的部门的部门编号
SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
ORDER BY AVGSAL DESC
LIMIT 1;
-- (2)把上面的查询结果当做一个临时表T,和DEPT 表进行连接
SELECT T.DEPTNO ,D.DNAME,T.AVGSAL
FROM DEPT D
INNER JOIN ( SELECT DEPTNO ,AVG(SAL) AVGSAL
FROM EMP
GROUP BY DEPTNO
ORDER BY AVGSAL DESC
LIMIT 1) T ON (D.DEPTNO = T.DEPTNO);
- 方式2: 把dept和emp进行连接查询,然后按照部门名称进行分组,并且将查询结果按照平均工资降序排列,使用limit取得第一条结果
SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME
ORDER BY AVGSAL DESC
LIMIT 1;
7.求平均薪水的等级最低(高)的部门的部门名称
- (1).查询并且薪水及其部门名称,也就是把EMP表和DEPT表进行连接查询,然后按照部门名称进行分组
SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME;
- (2)把上面的查询结果当做一个临时表T,和SALGRADE 表进行连接,查询平均工资的级别
SELECT T.DNAME,T.AVGSAL ,S.GRADE
FROM ( SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME) T
INNER JOIN SALGRADE S ON (T.AVGSAL BETWEEN S.LOSAL AND S.HISAL);
- (3)把上面的查询结果当做一个临时表T,查询最大的工资级别
SELECT MAX(T.GRADE) MAXGRADE
FROM (SELECT T.DNAME,T.AVGSAL ,S.GRADE
FROM ( SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME) T
INNER JOIN SALGRADE S ON (T.AVGSAL BETWEEN S.LOSAL AND S.HISAL)) T;
- (4)把上面的查询结果当做添加,过滤第二步的查询结果
SELECT T.DNAME,T.AVGSAL ,S.GRADE
FROM ( SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME) T
INNER JOIN SALGRADE S ON (T.AVGSAL BETWEEN S.LOSAL AND S.HISAL)
WHERE S.GRADE = ( SELECT MAX(T.GRADE) MAXGRADE
FROM ( SELECT T.DNAME,T.AVGSAL ,S.GRADE
FROM ( SELECT D.DNAME,AVG(E.SAL) AVGSAL
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME) T
INNER JOIN SALGRADE S ON (T.AVGSAL BETWEEN S.LOSAL AND S.HISAL)) T );
8.取得比普通员工的最高薪水还要高的经理人姓名
-
-- 思路:
-- (1)查询出所有的经理的编号,也就是出现在MGR中的员工编号
SELECT DISTINCT MGR FROM EMP ;
-- (2)查询员工的编号,也就是EMPNO没有出现在经理编号
/*
SELECT *
FROM EMP
WHERE EMPNO NOT IN ( SELECT DISTINCT MGR FROM EMP );
上面的语句查询不到结果,这是因为 EMPNO NOT IN (7788,NULL) 等效于 EMPNO <> 7788 OR EMPNO <> NULL
IN会自动的忽略空值
所以需要我们手动的排除空值,改正上面的语句
*/
SELECT *
FROM EMP
WHERE EMPNO NOT IN ( SELECT DISTINCT MGR FROM EMP WHERE MGR IS NOT NULL );
-- (3)查询所有员工的最高工资,也就是把上面的查询结果单做一个临时表T,
SELECT MAX(T.SAL) MAXSAL
FROM ( SELECT *
FROM EMP
WHERE EMPNO NOT IN ( SELECT DISTINCT MGR FROM EMP WHERE MGR IS NOT NULL )) T;
-- (4)把上面的查询结果当做条件
SELECT *
FROM EMP
WHERE SAL > ( SELECT MAX(T.SAL) MAXSAL
FROM ( SELECT *
FROM EMP
WHERE EMPNO NOT IN ( SELECT DISTINCT MGR FROM EMP WHERE MGR IS NOT NULL )) T);
9.取得薪水最高的前五名员工
-- (1)查询员工表的信息,按照工资降序排列
SELECT * FROM EMP ORDER BY SAL DESC;
-- (2)使用LIMIT取得前5条记录
SELECT * FROM EMP ORDER BY SAL DESC LIMIT 0,5; -- 从0开始,取5条记录
SELECT * FROM EMP ORDER BY SAL DESC LIMIT 5; -- 默认的就是从0开始的
/*******************************************豪华的分割线*************************************************/
-- 10.取得薪水最高的第六到第十名员工
-- (1)查询员工表的信息,按照工资降序排列
SELECT * FROM EMP ORDER BY SAL DESC;
-- (2)使用LIMIT取得6~10位的数据
SELECT * FROM EMP ORDER BY SAL DESC LIMIT 5,5; -- 从5开始,连续的5条记录
11.取得最后(也就是最大的日期)入职的5名员工
-- 日期类型的数据也是有大小的,日期类型数据的大小可以由其字面值来决定,例如"1987"小于"2018"
-- (1)查询员工信息,按照入职日期降序排列
SELECT * FROM EMP ORDER BY HIREDATE DESC;
-- (2)使用LIMIT取得前5条记录
SELECT * FROM EMP ORDER BY HIREDATE DESC LIMIT 5;
12.取得每个薪水等级有多少员工
-- (1)查询员工的薪水级别(把emp表和salgrade表进行连接)
SELECT E.SAL ,S.GRADE
FROM EMP E
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL);
-- (2)使用GRADE进行分组,查询每组的数据总数(count())
SELECT count(*) ,S.GRADE
FROM EMP E
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
GROUP BY S.GRADE;
14.列出所有员工及领导的名字
/*
-- 使用自连接进行查询
SELECT E.EMPNO "员工编号",E.ENAME "员工姓名",M.EMPNO "经理编号",M.ENAME "经理姓名"
FROM EMP E
INNER JOIN EMP M ON (E.MGR = M.EMPNO);
上面的语句是错误的,因为没有查询出7839这个人的经理;因为内连接只能查询满足一一对应关系的数据
我们要查询出不满足对应关系的7839,应该使用外连接
改正上面的语句
*/
SELECT E.EMPNO "员工编号",E.ENAME "员工姓名",M.EMPNO "经理编号",M.ENAME "经理姓名"
FROM EMP E
LEFT JOIN EMP M ON (E.MGR = M.EMPNO);
15.列出受雇日期早于其直接上级的所有员工编号、姓名、部门名称
-- (1)查询员工其经理
SELECT E.EMPNO "员工编号",E.ENAME "员工姓名",M.EMPNO "经理编号",M.ENAME "经理姓名"
FROM EMP E
LEFT JOIN EMP M ON (E.MGR = M.EMPNO);
-- (2)使用受雇日期早于其直接上级的日期作为条件,对上面的结果进行过滤
SELECT E.EMPNO "员工编号",E.ENAME "员工姓名" ,E.DEPTNO "部门编号",M.EMPNO "经理编号",M.ENAME "经理姓名"
FROM EMP E
LEFT JOIN EMP M ON (E.MGR = M.EMPNO)
WHERE E.HIREDATE < M.HIREDATE;
-- (3)把上面的查询结果和DEPT表进行连接
SELECT T.EMPNO,T.ENAME ,T.DEPTNO ,D.DNAME
FROM DEPT D
INNER JOIN ( SELECT E.EMPNO ,E.ENAME,E.DEPTNO
FROM EMP E
LEFT JOIN EMP M ON (E.MGR = M.EMPNO)
WHERE E.HIREDATE < M.HIREDATE) T ON (D.DEPTNO = T.DEPTNO)
ORDER BY T.DEPTNO;
16.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门
SELECT * FROM EMP;
SELECT * FROM DEPT;
-- 使用外连接进行查询
SELECT E.EMPNO,E.ENAME,D.DEPTNO,D.DNAME
FROM EMP E
RIGHT OUTER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);
17.列出至少有5个员工的所有部门
-- (1)把dept和emp进行连接查询
SELECT E.EMPNO ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);
-- (2)对上的查询结果进行分组(按照deptno,dname,loc进行分组),并且查询每组的记录总数
SELECT COUNT(E.EMPNO) TOTAL ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DEPTNO,D.DNAME,D.LOC;
-- (3)使用HAVGING对分组后的数据进行过滤
SELECT COUNT(E.EMPNO) TOTAL ,D.DEPTNO,D.DNAME,D.LOC
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DEPTNO,D.DNAME,D.LOC
HAVING TOTAL >= 5;
18.列出薪水比“SMITH”多的所有员工信息
-- (1)查询"smith"的工资
SELECT SAL FROM EMP WHERE ENAME = "SMITH";
-- (2)用上面的查询结果当做查询条件,也就是使用一个出现在WHERE后面的子查询
SELECT *
FROM EMP
WHERE SAL > ( SELECT SAL FROM EMP WHERE ENAME = "SMITH" );
19.列出所有“CLERK”(办事员)的姓名及其部门名称,部门人数
-- (1)查询所有办事员的姓名及其部门名称,用一个等值连接(EMP,DEPT)
SELECT E.ENAME,E.JOB,D.DEPTNO ,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.JOB = "CLERK";
-- (2)按照部门编号分组,查询每个部门的员工总数
SELECT DEPTNO ,COUNT(*) TOTALEMP
FROM EMP
GROUP BY DEPTNO;
-- (3)把上面的两个查询结果当做临时表t1,t2 ,做一个连接查询
SELECT T1.ENAME,T1.JOB,T1.DEPTNO,T1.DNAME ,T2.TOTALEMP
FROM (SELECT E.ENAME,E.JOB,D.DEPTNO ,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.JOB = "CLERK") T1
INNER JOIN (SELECT DEPTNO ,COUNT(*) TOTALEMP
FROM EMP
GROUP BY DEPTNO) T2 ON (T1.DEPTNO = T2.DEPTNO);
20.列出最低薪水大于1500的各种工作及从事此工作的全部雇员人数
-- (1)列出最低薪水大于1500的各种工作,按照职务分组查询最低工资,并且过滤大于1500的记录
SELECT JOB ,MIN(SAL) MINSAL
FROM EMP
GROUP BY JOB
HAVING MINSAL > 1500;
-- (2)在上面查询结果的基础上出现员工总数
SELECT JOB ,MIN(SAL) MINSAL ,COUNT(*) TOTAL
FROM EMP
GROUP BY JOB
HAVING MINSAL > 1500;
-- (3)校验数据
SELECT *
FROM EMP
WHERE SAL > 1500
ORDER BY JOB;
21.列出在部门“SALES”<销售部>工作的员工的姓名,假定不知道销售部门的部门编号销售部>
-- (1)从部门表中查询"SALES"的部门编号
SELECT DEPTNO FROM DEPT WHERE DNAME = "SALES";
-- (2)用上面的查询结果当做查询条件,也就是使用出现在WHERE中的子查询
SELECT DEPTNO,ENAME
FROM EMP WHERE DEPTNO = (SELECT DEPTNO FROM DEPT WHERE DNAME = "SALES");
22.列出薪金高于公司平均薪金的所有员工,所在部门、上级领导、雇员的工资等级
-- (1)列出薪金高于公司平均薪金的所有员工
SELECT E.ENAME ,E.SAL
FROM EMP E
WHERE E.SAL > (SELECT AVG(SAL) FROM EMP )
-- (2)在上面的查询基础上,查询上级领导(使用自连接) ,员工的工资级别(和SALGRADE 表进行连接)
SELECT E.ENAME "员工姓名",E.SAL "员工工资" ,S.GRADE "工资级别",E.DEPTNO "部门编号" ,M.ENAME "经理姓名"
FROM EMP E
INNER JOIN EMP M ON (E.MGR = M.EMPNO)
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
WHERE E.SAL > (SELECT AVG(SAL) FROM EMP )
-- (3)把KING也查询出来,也就是做自连接时候使用外连接方式,
SELECT E.ENAME "员工姓名",E.SAL "员工工资" ,S.GRADE "工资级别",E.DEPTNO "部门编号" ,M.ENAME "经理姓名"
FROM EMP E
LEFT JOIN EMP M ON (E.MGR = M.EMPNO)
INNER JOIN SALGRADE S ON (E.SAL BETWEEN S.LOSAL AND S.HISAL)
WHERE E.SAL > (SELECT AVG(SAL) FROM EMP );
23.列出与“SCOTT”从事相同工作的所有员工及部门名称
-- (1)查询出和SCOTT从事相同职务的员工,使用是一个出现在WHERE后面的子查询
SELECT ENAME,JOB
FROM EMP
WHERE JOB = (SELECT JOB FROM EMP WHERE ENAME ="SCOTT");
-- (2)在上面查询的基础上,连接DEPT表
SELECT E.ENAME,E.JOB , D.DEPTNO,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.JOB = (SELECT JOB FROM EMP WHERE ENAME ="SCOTT");
24.列出薪金等于部门30中员工的薪金的其它员工的姓名和薪金
-- (1)查询出30部门的员工工资
SELECT SAL FROM EMP WHERE DEPTNO = 30;
-- (2)把上面的查询结果当做查询条件,也就是使用出现在WHERE后面子查询
SELECT SAL ,ENAME ,DEPTNO
FROM EMP
WHERE SAL IN (SELECT SAL FROM EMP WHERE DEPTNO = 30) AND (DEPTNO <> 30);
25.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金、部门名称
-- 方式1:
-- (1)查询30部门的最高工资
SELECT MAX(SAL) MAXSAL FROM EMP WHERE DEPTNO = 30;
-- (2)用上面的查询结果当做查询条件,并且和DEPT进行连接查询查询出部门名称
SELECT E.ENAME ,E.SAL ,E.DEPTNO ,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE E.SAL > (SELECT MAX(SAL) MAXSAL FROM EMP WHERE DEPTNO = 30);
-- 方式2:
-- 如果子查询返回多行多列,需要使用多行比较操作符,用 > ALL,表示大于子查询的最大值
SELECT E.ENAME,E.SAL,E.DEPTNO ,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE SAL > ALL (SELECT SAL FROM EMP WHERE DEPTNO = 30)
-- 如果子查询返回多行多列,需要使用多行比较操作符,用 < ALL,表示小于子查询的最小值
SELECT E.ENAME,E.SAL,E.DEPTNO ,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
WHERE SAL < ALL (SELECT SAL FROM EMP WHERE DEPTNO = 30)
26.列出在每个部门工作的员工数量、平均工资和平均服务期限
-- (1)所有所有的部门信息及其员工信息
SELECT E.*,d.*
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO= D.DEPTNO);
-- (2)在上面查询的基础上用部门编号分组,查询员工总数
-- 注意,count(*)会查询包含null的数据,所以用count(ename)
SELECT D.DEPTNO,COUNT(ENAME) TOTALEMP
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO= D.DEPTNO)
GROUP BY D.DEPTNO;
-- (3)在上面的查询结果的基础上,查询平均工资
SELECT D.DEPTNO,COUNT(ENAME) TOTALEMP ,IFNULL( AVG(SAL),0) AVGSAL
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO= D.DEPTNO)
GROUP BY D.DEPTNO
-- (4)在上面的查询结果的基础上,查询平均服务年限
-- Mysql中有一个TO_DAYS()函数,把一个日期转换为天数(距离0年的天数)
SELECT AVG((TO_DAYS(NOW()) - TO_DAYS(HIREDATE)) / 365)
FROM EMP;
SELECT D.DEPTNO,COUNT(ENAME) TOTALEMP ,IFNULL( AVG(SAL),0) AVGSAL,
IFNULL( AVG((TO_DAYS(NOW()) - TO_DAYS(HIREDATE)) / 365),0 ) SERVERTIME
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO= D.DEPTNO)
GROUP BY D.DEPTNO
27.列出所有员工的姓名、部门名称和工资
-- 连接EMP,DEPT表,做等值连接
-- SQL1999语句
SELECT E.ENAME,E.SAL,D.DNAME
FROM EMP E
INNER JOIN DEPT D ON (E.DEPTNO = D.DEPTNO);
-- SQL1992语句
SELECT E.ENAME,E.SAL,D.DNAME
FROM EMP E,DEPT D
WHERE E.DEPTNO = D.DEPTNO;
28.列出所有部门的详细信息和人数
-- 用外连接,连接emp表和dept表,然后按照部门编号分组,查询员工总数
SELECT D.DEPTNO, D.DNAME,D.LOC ,COUNT(ENAME) TOTALEMP
FROM EMP E
RIGHT JOIN DEPT D ON (E.DEPTNO = D.DEPTNO)
GROUP BY D.DEPTNO,D.DNAME,D.LOC ;
29.列出各种工作的最低工资及从事此工作的雇员姓名
-- (1)按照职务分组,查询最低工资
SELECT JOB,MIN(SAL) MINSAL
FROM EMP
GROUP BY JOB;
-- (2)把上面的查询结果当做临时表t,和EMP表进行连接查询
SELECT E.ENAME,T.JOB,T.MINSAL
FROM EMP E
INNER JOIN (SELECT JOB,MIN(SAL) MINSAL
FROM EMP
GROUP BY JOB) T ON (E.JOB = T.JOB AND E.SAL = T.MINSAL);
30.列出各个部门MANAGER的最低薪金
-- (1)查询职务为"MANAGER"的员工信息
SELECT *
FROM EMP
WHERE JOB = "MANAGER";
-- (2)在上面查询的基础上,按照部门编号分组,查询最低工资
SELECT DEPTNO,MIN(SAL) MINSAL
FROM EMP
WHERE JOB = "MANAGER"
GROUP BY DEPTNO;
31.列出所有员工的年工资,按年薪从低到高排序
-- 年薪 = (月薪+津贴) * 12
SELECT EMPNO,ENAME, SAL, COMM, (SAL+ IFNULL(COMM,0)) * 12 AS "年薪"
FROM EMP
ORDER BY 年薪 ;
SELECT EMPNO,ENAME, SAL, COMM, (SAL+ IFNULL(COMM,0)) * 12 AS "年薪"
FROM EMP
ORDER BY 年薪 ASC;
SELECT EMPNO,ENAME, SAL, COMM, (SAL+ IFNULL(COMM,0)) * 12 AS "年薪"
FROM EMP
ORDER BY 年薪 DESC;
32.求出员工领导的薪水超过3000的员工名称和领导名称
-- (1)使用自连接查询员工信息及其领导信息
SELECT E.ENAME "员工姓名" ,E.SAL "员工工资" ,M.ENAME "经理姓名" ,M.SAL "经理工资"
FROM EMP E
INNER JOIN EMP M ON (E.MGR = M.EMPNO);
-- (2)在上面查询的基础上,加上查询条件,领导的工资大于3000
-- 在加入其它的的查询条件的时候,可以使用WHERE
SELECT E.ENAME "员工姓名" ,E.SAL "员工工资" ,M.ENAME "经理姓名" ,M.SAL "经理工资"
FROM EMP E
INNER JOIN EMP M ON (E.MGR = M.EMPNO)
WHERE M.SAL > 3000;
-- 在加入其它的的查询条件的时候,可以使用WHERE ,也可以使用AND
SELECT E.ENAME "员工姓名" ,E.SAL "员工工资" ,M.ENAME "经理姓名" ,M.SAL "经理工资"
FROM EMP E
INNER JOIN EMP M ON (E.MGR = M.EMPNO) AND (M.SAL > 3000);
33.求部门名称中带“S”字符的部门员工的工资合计、部门人数
-- (1)查询出部门名称,工资合计,部门人数
SELECT D.DNAME, IFNULL(SUM(SAL),0) SUMSAL ,COUNT(ENAME) TOTALEMP
FROM EMP E
RIGHT JOIN DEPT D ON(E.DEPTNO = D.DEPTNO)
GROUP BY D.DNAME;
-- 在上面的查询基础是上,加上条件:部门名称中带“S”字符
SELECT D.DNAME, IFNULL(SUM(SAL),0) SUMSAL ,COUNT(ENAME) TOTALEMP
FROM EMP E
RIGHT JOIN DEPT D ON(E.DEPTNO = D.DEPTNO)
WHERE D.DNAME LIKE "%S%"
GROUP BY D.DNAME;
34.给任职日期超过30年的员工加薪10%
DROP TABLE IF EXISTS EMP_BAK;
CREATE TABLE EMP_BAK AS SELECT * FROM EMP ;
SELECT * FROM EMP_bak;
UPDATE EMP_BAK SET SAL=SAL*1.1 WHERE (( TO_DAYS(NOW()) - TO_DAYS(HIREDATE)) / 365 > 30)