目录
3.11 列出所有"CLERK"( 办事员) 的姓名及其部门名称, 部门的人数
3.12 列出最低薪金大于 1500 的各种工作及从事此工作的全部雇员人数按照工作岗位分组求最小值。
3.13 列出在部门"SALES"< 销售部> 工作的员工的姓名, 假定不知道销售部的部门编号.
3.14 列出薪金高于公司平均薪金的所有员工, 所在部门, 上级领导, 雇员的工资等级.
3.15 列出与"SCOTT" 从事相同工作的所有员工及部门名称
3.16 列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金. 部门名称
对之前学习的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;
3.13 列出在部门"SALES"< 销售部> 工作的员工的姓名, 假定不知道销售部的部门编号.
查询出部门为:”SALES“的部门编号之后再到emp表中进行条件查询
select ENAME as '名字' from emp
where deptno = (select DEPTNO from dept where DNAME = 'SALES')
3.14 列出薪金高于公司平均薪金的所有员工, 所在部门, 上级领导, 雇员的工资等级.
-
使用INNER JOIN将EMP表(e)和DEPT表(d)连接,以获取员工和所在部门的相关信息。
-
使用INNER JOIN将员工的薪金与工资等级表(SALGRADE)进行连接,以获取工资等级信息。
-
使用LEFT JOIN将员工的上级领导(通过mgr列关联)与员工表连接,以获取上级领导的姓名。
-
使用WHERE子句筛选出薪金高于公司平均薪金的员工。
select e.ENAME as '名字',e.SAL as '薪资', (select avg(SAL) from emp) as '平均薪资', d.DNAME as '部门名称',s.GRADE as '薪资等级',e2.ENAME as '上级领导'
from emp e
inner join dept d on e.DEPTNO = d.DEPTNO
inner join salgrade s on e.SAL between s.LOSAL and s.HISAL
left join emp e2 on e.mgr = e2.EMPNO
where e.SAL > (select avg(SAL) from emp);
3.15 列出与"SCOTT" 从事相同工作的所有员工及部门名称
先查出”scott“所从事的工作,之后在与dept进行连接查出跟其所从事一样的工作的人及工作部门,然后使用个否定进行筛选掉‘scott’即可
select e.ENAME as '名字',d.DNAME as '部门名称',e.JOB as '工作'
from emp e
inner join dept d on e.DEPTNO = d.DEPTNO
where e.JOB = (select JOB as '名字' from emp where ENAME = 'SCOTT')
and e.ENAME <> 'SCOTT';
3.16 列出薪金高于在部门 30 工作的所有员工的薪金的员工姓名和薪金. 部门名称
筛选出部门编号为:30的部门的最高薪资,以此为条件,然后连接dept表
select e.ENAME ,e.SAL ,d.DNAME from emp e
inner join dept d on e.DEPTNO = d.DEPTNO
where e.SAL > (select max(SAL) from emp where DEPTNO = 30);
3.17 列出在每个部门工作的员工数量, 平均工资
连接emp表和dept表,根据DNAME进行分组,利用count函数计算出总数和avg计算出平均薪资
select d.DNAME as '部门名称' ,count(*) as '员工数量' ,avg(e.SAL) from emp e
inner join dept d where e.DEPTNO = d.DEPTNO group by d.DNAME;
3.18 列出所有员工的姓名、部门名称和工资。
这个直接使用连接二张表即可
select e.ENAME,d.DNAME,e.SAL from emp e inner join dept d on e.DEPTNO = d.DEPTNO;
3.19 列出所有部门的详细信息和人数
select d.DEPTNO, d.DNAME, d.LOC,count(e.ENAME) as '部门人数' from emp e
right join dept d on d.DEPTNO = e.DEPTNO group by d.deptno;
3.20 列出各种工作的最低工资及从事此工作的雇员姓名
这里使用工作来进行分组筛选即可,但是可能会忽略的问题是,存在多个员工工资都是最低的情况
这个可以使用 GROUP_CONCAT(e.ename) 进行合并,这个函数的作用就是将一个分组内的多个值合并成一个逗号分隔的字符串。
SELECT e.job AS "工作岗位", MIN(e.sal) AS "最低工资", GROUP_CONCAT(e.ename) AS "雇员姓名"
FROM emp e
GROUP BY e.job;
后续会继续增加些题目。。。。。。