目录
1.准备数据表
2.表之间的关系
3.题目
3.1 取得每个部门最高薪水的人员名称
3.2 哪些人的薪水在部门的平均薪水之上
3.3 取得部门中(所有人的)平均的薪水等级
3.4 不准用组函数(Max ),取得最高薪水
3.5 取得平均薪水最高的部门的部门编号
3.5 取得平均薪水最高的部门的部门名称
3.6 取得薪水最高的第六至第十名员工
3.7 取得每个薪水等级有多少员工
3.8 列出所有员工及领导的名字
3.9 列出至少有5个员工的所有部门
3.10 列出薪金比"SMITH" 多的所有员工信息
3.11 列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数
3.12 列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数按照工作岗位分组求最小值。
对之前学习的mysql基础和进阶进行一些练习,巩固前面学完的知识。
1.准备数据表
CREATE TABLE DEPT
(DEPTNO int(2) not null ,
DNAME VARCHAR(14) ,
LOC VARCHAR(13),
primary key (DEPTNO)
);
CREATE TABLE EMP
(EMPNO int(4) not null ,
ENAME VARCHAR(10),
JOB VARCHAR(9),
MGR INT(4),
HIREDATE DATE DEFAULT NULL,
SAL DOUBLE(7,2),
COMM DOUBLE(7,2),
primary key (EMPNO),
DEPTNO INT(2)
)
;
CREATE TABLE SALGRADE
( GRADE INT,
LOSAL INT,
HISAL INT );
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
10, 'ACCOUNTING', 'NEW YORK');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
20, 'RESEARCH', 'DALLAS');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
30, 'SALES', 'CHICAGO');
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES (
40, 'OPERATIONS', 'BOSTON');
commit;
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7369, 'SMITH', 'CLERK', 7902, '1980-12-17'
, 800, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7499, 'ALLEN', 'SALESMAN', 7698, '1981-02-20'
, 1600, 300, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7521, 'WARD', 'SALESMAN', 7698, '1981-02-22'
, 1250, 500, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7566, 'JONES', 'MANAGER', 7839, '1981-04-02'
, 2975, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7654, 'MARTIN', 'SALESMAN', 7698, '1981-09-28'
, 1250, 1400, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7698, 'BLAKE', 'MANAGER', 7839, '1981-05-01'
, 2850, NULL, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7782, 'CLARK', 'MANAGER', 7839, '1981-06-09'
, 2450, NULL, 10);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7788, 'SCOTT', 'ANALYST', 7566, '1987-04-19'
, 3000, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7839, 'KING', 'PRESIDENT', NULL, '1981-11-17'
, 5000, NULL, 10);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7844, 'TURNER', 'SALESMAN', 7698, '1981-09-08'
, 1500, 0, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7876, 'ADAMS', 'CLERK', 7788, '1987-05-23'
, 1100, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7900, 'JAMES', 'CLERK', 7698, '1981-12-03'
, 950, NULL, 30);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7902, 'FORD', 'ANALYST', 7566, '1981-12-03'
, 3000, NULL, 20);
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES (
7934, 'MILLER', 'CLERK', 7782, '1982-01-23'
, 1300, NULL, 10);
commit;
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
1, 700, 1200);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
2, 1201, 1400);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
3, 1401, 2000);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
4, 2001, 3000);
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES (
5, 3001, 9999);
commit;
之间运行上面的sql,需要用到的数据表就建立好了。
2.表之间的关系
-
DEPT(部门表):
- DEPTNO:部门编号,整数类型,主键。
- DNAME:部门名称。
- LOC:部门所在地。
-
EMP(员工表):
- EMPNO:员工编号,整数类型,主键。
- ENAME:员工姓名。
- JOB:员工职位。
- MGR:上级经理的员工编号,整数类型。
- HIREDATE:入职日期,日期类型,默认为NULL。
- SAL:薪资。
- COMM:奖金。
- DEPTNO:所属部门编号,整数类型。
-
SALGRADE(薪资等级表):
- GRADE:薪资等级,整数类型。
- LOSAL:最低薪资,整数类型。
- HISAL:最高薪资,整数类型。
3.题目
3.1 取得每个部门最高薪水的人员名称
思路:
-
使用INNER JOIN将EMP表和DEPT表连接,以获取员工和其所在部门的相关信息。
-
使用子查询,计算每个部门的最高薪水。子查询中使用GROUP BY和MAX函数来找到每个部门的最高薪水。
-
在主查询中,通过比较员工的薪水和其所在部门的最高薪水,筛选出薪水等于最高薪水的员工。
-
结果集中包括了每个部门中薪水最高的员工的姓名、部门名称和薪水。
select d.dname as "部门名称", e.ename as "员工姓名", e.sal as "薪水"
from emp e
inner join dept d on e.deptno = d.deptno
where (e.deptno, e.sal) in (
select deptno, max(sal)
from emp
group by deptno
);
结果:
3.2 哪些人的薪水在部门的平均薪水之上
思路:
-
主查询中使用INNER JOIN连接EMP表(e)和DEPT表(d),以获取员工和其所在部门的相关信息。
-
使用INNER JOIN连接一个子查询,该子查询计算每个部门的平均薪水。子查询中使用GROUP BY和AVG函数来计算每个部门的平均薪水。
-
在主查询中,通过比较员工的薪水(e.sal)和其所在部门的平均薪水(dept_avg.avg_dept_salary),筛选出薪水高于所在部门平均薪水的员工。
-
结果集包括了员工姓名、员工薪水、部门名称和部门平均薪水,以便比较员工薪水与部门平均薪水。
SELECT e.ename AS "员工姓名", e.sal AS "员工薪水", d.dname AS "部门名称", avg_dept_salary AS "部门平均薪水"
FROM emp e
INNER JOIN dept d ON e.deptno = d.deptno
INNER JOIN (
SELECT deptno, AVG(sal) AS avg_dept_salary
FROM emp
GROUP BY deptno
) dept_avg ON e.deptno = dept_avg.deptno
WHERE e.sal > dept_avg.avg_dept_salary;
结果:
3.3 取得部门中(所有人的)平均的薪水等级
1.首先要取得所有人的薪水等级再按部门编号分组
2.按照部门编号分组后再取平均值
select e.DEPTNO as '部门编号',avg(s.GRADE) as '部门平均薪资等级'
from emp e
inner join salgrade s
on e.SAL between s.LOSAL and s.HISAL group by e.DEPTNO;
3.4 不准用组函数(Max ),取得最高薪水
第一种方法:使用降序取第一个数据
select ENAME,SAL from emp order by SAL desc limit 1;
第二种方法:使用自连接再进行not in 去查找
select SAL from emp where sal
not in (select distinct a.SAL from emp a join emp b on a.SAL < b.SAL)
3.5 取得平均薪水最高的部门的部门编号
用avg取平均值,按照deptno分组,最后降序排序取第一个值
select DEPTNO as '部门编号',avg(SAL) as '平均薪水' from emp
group by DEPTNO order by avg(SAL) desc limit 1;
3.5 取得平均薪水最高的部门的部门名称
按照dname来分组最后采用降序排序
select d.DNAME,avg(e.SAL) as avgsal from emp e
join dept d
on e.DEPTNO = d.DEPTNO
group by d.DNAME
order by avgsal desc limit 1;
3.6 取得薪水最高的第六至第十名员工
降序排序取6-10
select ENAME,SAL from emp order by sal desc limit 5,5;
3.7 取得每个薪水等级有多少员工
按照grand进行分组再求和
select s.GRADE,COUNT(*) from emp e
inner join salgrade s
on e.SAL between s.LOSAL and s.HISAL
group by s.GRADE;
3.8 列出所有员工及领导的名字
select a.ENAME '员工' ,b.ENAME '领导' from emp a
left join emp b on a.mgr = b.EMPNO;
3.9 列出至少有5个员工的所有部门
-
使用INNER JOIN将EMP表(e)和DEPT表(d)连接,以获取员工和其所在部门的相关信息。
-
使用GROUP BY子句按部门名称(d.dname)进行分组,以计算每个部门中的员工数量。
-
使用HAVING子句筛选出员工数量至少为5的部门。
select d.DNAME as '部门名称',count(*) as '员工数量'
from emp e inner join dept d on e.DEPTNO = d.DEPTNO
group by d.DNAME having count(*) >= 5;
3.10 列出薪金比"SMITH" 多的所有员工信息
直接筛选出来然后比较就行
select ENAME,SAL from emp
where SAL > (select SAL from emp where ename = 'SMITH') order by SAL desc ;
3.11 列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数
1.从EMP表中选择职位为"CLERK"的员工的姓名(ename)、所在部门编号(deptno)。
2.使用INNER JOIN将上述查询结果与DEPT表连接,以获取员工所在部门的名称(dname)。
3.使用子查询计算每个部门的员工人数,并使用GROUP BY子句按部门编号进行分组。
4.最后,将上述查询的结果用作子查询,并再次使用INNER JOIN将部门人数(deptcount)与部门名称(dname)连接,以获取最终结果。
SELECT t1.ename AS "员工姓名", t1.dname AS "部门名称", t2.deptcount AS "部门人数"
FROM (
SELECT e.ename, d.dname, e.deptno
FROM emp e
JOIN dept d ON e.deptno = d.deptno
WHERE e.job = 'CLERK'
) t1
JOIN (
SELECT deptno, COUNT(*) AS deptcount
FROM emp
GROUP BY deptno
) t2 ON t1.deptno = t2.deptno;
3.12 列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数按照工作岗位分组求最小值。
select job,sal, count(*) as '从事该工作工资低于1500的人数' from emp
group by job having min(SAL) > 1500;
后续会继续增加些题目。。。。。。