首先建立测试数据库的表,新建数据库的sql语句如下,大家可以粘贴成一个sql文件,然后新建所有的表并插入所有的数据:
新建数据库sql文件:
- DROP TABLE IF EXISTS EMP;
- DROP TABLE IF EXISTS DEPT;
- DROP TABLE IF EXISTS SALGRADE;
-
- 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;
-
现在我们可以看到有3张表,分别是:emp(员工信息表)、dept(部门信息表)、salgrade(薪水等级表),三张表的各个构成如下:
emp(员工信息表)

dept(部门信息表)

salgrade(薪水等级表)

第一题:取得每个部门最高薪水的人员名称

思路:
SELECT DEPTNO,max(sal)as avgsal FROM `emp`GROUP BY DEPTNO;
先找出每个部门的最高薪水,然后作为临时表与emp连接查询该薪水对应的员工。
答案:
- SELECT
- emp.ENAME,t.*
- FROM
- emp
- JOIN
- (SELECT DEPTNO,max(sal)as maxsal FROM `emp`GROUP BY DEPTNO)t
- ON
- t.DEPTNO = emp.DEPTNO
- and
- t.maxsal = emp.SAL
第二题:哪些人薪水在部门的平均薪水之上

思路:
SELECT DEPTNO,avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO
同样先找出每个部门的平均薪资,然后再作为临时表和emp连接查询大于此工资的人
答案:
- SELECT
- emp.ENAME,emp.SAL,t.*
- FROM
- emp
- JOIN
- (SELECT DEPTNO,avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO)t
- on
- t.DEPTNO = emp.DEPTNO
- and
- emp.SAL>t.avgsal
第三题:取得部门中(所有人的)平均薪水的等级 / 平均的薪水等级
(1)平均薪水的等级

思路:先找出平均薪水再去连接薪水等级表得到等级
答案:
- SELECT
- salgrade.GRADE,t.*
- FROM
- salgrade
- JOIN
- (SELECT DEPTNO,avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO)t
- on
- t.avgsal BETWEEN salgrade.LOSAL and salgrade.HISAL
(2)平均的薪水等级

思路:先连接薪水等级的表,然后再算等级的平均值
答案:
- SELECT
- emp.DEPTNO,avg(salgrade.GRADE)as avgGRADE
- FROM
- emp
- JOIN
- salgrade
- on
- emp.SAL BETWEEN salgrade.LOSAL and salgrade.HISAL
- GROUP BY emp.DEPTNO
第四题:不用组函数(Max),取得最高薪水

思路:通过排序+limit 1 来获取最值
答案:
- SELECT
- emp.ENAME,emp.SAL
- FROM
- emp
- ORDER BY emp.SAL DESC LIMIT 1
第五题:取得平均薪水最高的部门的部门名称

思路:先计算各部门的平均薪水得到临时表,然后和部门信息表连接获取名称,并用max获取最值
答案:
第一种:
- SELECT
- dept.DNAME, max(t.avgsal)as maxavgsal
- FROM
- dept
- JOIN
- (SELECT DEPTNO,avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO)t
- on dept.DEPTNO = t.DEPTNO
第二种:
- SELECT
- dept.DNAME, max(t.avgsal)as maxavgsal
- FROM
- dept
- JOIN
- (SELECT DEPTNO,avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO ORDER BY avgsal DESC LIMIT 1)t
- on dept.DEPTNO = t.DEPTNO
【重要】第六题:求平均薪水等级最低的部门的部门名称

思路:先求平均薪水最低的部门,然后用薪水连接薪水等级表对应等级,用部门编号连接部门信息表对应部门名称。
- 求出最低平均值
- SELECT avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO ORDER BY avgsal ASC LIMIT 1
-
- 求出最低平均值对应等级
- SELECT salgrade.GRADE FROM salgrade JOIN (SELECT avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO ORDER BY avgsal ASC LIMIT 1)r on r.avgsal BETWEEN salgrade.LOSAL and salgrade.HISAL
-
- 求出dept和salgrade联合
- select dept.DNAME,avg(sal)as avgsal FROM emp JOIN dept on emp.DEPTNO = dept.DEPTNO GROUP BY emp.DEPTNO
答案:
- SELECT
- t.*,salgrade.GRADE
- FROM
- (select dept.DNAME,avg(sal)as avgsal FROM emp JOIN dept on emp.DEPTNO = dept.DEPTNO GROUP BY emp.DEPTNO)t join
- salgrade
- on
- t.avgsal BETWEEN salgrade.LOSAL and salgrade.HISAL
- WHERE
- GRADE = (SELECT
- salgrade.GRADE
- FROM
- salgrade
- JOIN
- (SELECT avg(sal)as avgsal FROM `emp`GROUP BY DEPTNO ORDER BY avgsal ASC LIMIT 1)r
- on r.avgsal BETWEEN salgrade.LOSAL and salgrade.HISAL)
第七题:取得比普通员工(员工代码没有在mgr字段上出现的)的最高薪水还要高的领导人姓名

思路:
1、先找出领导人编号MGR
2、然后找出非领导人(普通员工)的最高薪水maxsal
3、然后再整个emp中查找薪水>maxsal且编号属于领导的员工姓名
答案:
- SELECT
- ENAME
- FROM
- emp WHERE SAL>(
- SELECT
- max(SAL)as maxsal
- FROM
- emp
- WHERE EMPNO NOT in(
- SELECT DISTINCT
- MGR
- FROM
- emp
- WHERE
- MGR is NOT null))
- and
- EMPNO
- in (
- SELECT DISTINCT
- MGR
- FROM
- emp
- WHERE MGR is NOT null)
第八题:取得薪水最高的前五名
SELECT ENAME,SAL FROM emp ORDER BY SAL DESC LIMIT 5
第九题:取得薪水最高的6-10名
SELECT ENAME,SAL FROM emp ORDER BY SAL DESC LIMIT 5,5
第十题:取得最后入职的5名员工
SELECT ENAME,HIREDATE FROM emp ORDER BY HIREDATE DESC LIMIT 5
第十一题:取得每个薪水等级有多少员工

思路:先找出每个薪水对应的等级,然后按照等级分组,并进行count(*)
答案:
- SELECT
- salgrade.GRADE,count(*)
- FROM
- emp
- JOIN
- salgrade
- WHERE
- emp.SAL BETWEEN salgrade.LOSAL AND salgrade.HISAL
- GROUP BY
- salgrade.GRADE
【重要】第十二题:列出所有员工及对应领导的姓名

思路:通过emp表的自连接,a的MGR = b的员工编号得出其领导
答案:
- select
- a.ENAME '员工',b.ENAME '领导'
- from
- emp a
- left JOIN
- emp b
- on
- a.mgr = b.EMPNO
第十三题:列出受雇日期早于其上级领导的所有员工的编号、姓名、部门名称

思路:在上一题的基础上增加判断条件(a.HIREDATE 答案: 第十四题:列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门 第十五题:列出至少有5个员工的所有部门 第十六题:列出薪水比“SMITH”多的所有员工的信息 答案: 第十七题:列出所有“CLERK”(办事员)的姓名及其部门名称、部门的人数 思路: 1、先按照部门分组得出每个部门有多少人 2、与上面临时表连接,并判断JOB = 'CLERK'的员工在那些部门得出所在部门人数 3、与dept连接得到部门的名称 答案: 第十八题:列出最低薪金大于1500的各种工作及从事此工作的全部雇员人数 思路: 1、按照工作分组,求出各个工作的最低薪水 2、然后用emp与上面临时表相连,求出薪水大于最低薪水的人的信息,并进行count 或者直接按工作分组,求出最低薪水对应的工作,然后直接计算count,将条件放到having中。 答案: 第十九题:列出在部门“SALES”<销售部>工作的员工的姓名,假定不知道销售部的部门编号 答案: 【重要】第二十题:列出薪金高于公司平均薪金的所有员工,所在部门、上级领导、雇员的工资的等级 思路: 1、先求出平均薪水 2、然后就是,工资等级需要连接薪水等级表、所在部门需要连接dept 答案: 第二十一题:列出与“SCOTT”从事相同工作的所有员工及部门名称 思路:找出SCOTT从事的工作。然后连接dept表接口 答案: 第二十二题:列出薪金等于部门30中员工的薪金的其他员工的姓名和薪金 答案: 第二十三题:列出薪金高于部门30工作的所有员工的薪金的员工姓名和薪金,部门名称 思路: 1、先找出部门30中的最高薪水 2、连接dept获取部门名称即可 答案: 第二十四题:列出在每个部门工作的员工数量,平均工资和平均服务期限 思路:按照部门分组,注意日期的处理函数 答案: 第二十五题:列出所有员工的姓名、部门名称、工资 思路: 答案: 第二十六题:列出所有部门的详情信息和人数 答案: 第二十七题:列出各种工作的最低工资及从事此工作的雇员姓名 思路: 1、按照工作分组,得出各工作的最低薪水及工作 2、emp和临时表连接,判断条件为工作相同,薪水相同,从而得出雇员姓名 答案: 第二十八题:列出各个部门的MANAGER(领导)的最低薪金 思路: 1、与dept连接找出各个部门的MGR(因为有些部门可能没有人员,所以连接dept更精确) 2、按照部门分组,且工作等于MANAGER的人,求min(sal) 答案: 第二十九题:列出所有员工的年工资,按年薪从低到高排序 第三十题:求出员工领导薪水超过3000的员工名称与领导名称 思路:直接自连接,领导薪水>3000 答案: 第三十一题:求出部门名称中,带'S'字符的部门员工的工资合计、部门人数 思路:按部门分组,与dept连接,判断DNAME like "%S%" 答案: 第三十二题: 给任职日期超过30年的员工加薪10% 178.分数排名 编写 SQL 查询对分数进行排序。排名按以下规则计算: 按 查询结果格式如下所示。 结题思路:首先创建这张表 这个题这样梳理一下可能更容易理解: 最后的结果包含两个部分,第一部分是降序排列的分数,第二部分是每个分数对应的排名。 第一部分不难写: 比较难的是第二部分,假设现在有一个分数X,如何算出它的排名Rank呢?我们可以先提取出大于等于X的所有分数集合H,将H去重后的元素个数就是X的排名。可以按一下理解 我们要的是集合H去重之后的元素个数,因此变为如下所示: 那此时的X在题目中是什么,就是对应到第一部分的分数,所以这里的C就是a.Score,将两个部分结合起来为: 180.连续出现的数字 编写一个 SQL 查询,查找所有至少连续出现三次的数字。 返回的结果表中的数据可以按 任意顺序 排列。 查询结果格式如下面的例子所示: 解题思路: 首先这道题看起来很简单,但是比较复杂的一个点是连续出现三次,所以我们需要处理这个问题,我们通过多表连接即可实现。代码如下: 182:查找重复的电子邮箱 这个题目很简单,我们可以用having子句,having子句和where的区别是having子句是用在group by后面的条件语句。 答案: 184:部门工资最高的员工 首先,我们看到题目很简单的会直接连接两表分组求最值 得到的结果是: 但是在此题中,我们要注意的是每个部门最高工资的不仅只有一个人。所有我们不能直接两表连接,分组求最值,这样得出的结果每个部门只会有一个人,不符合题意。我们应该先求出每个部门的最高工资是多少,然后再连接用IN得出有哪些人是该工资。 185:部门工资前三高的所有员工 公司的主管们感兴趣的是公司每个部门中谁赚的钱最多。一个部门的 高收入者 是指一个员工的工资在该部门的 不同 工资中 排名前三 。 编写一个SQL查询,找出每个部门中 收入高的员工 。 答案: 此题首先需要得出的是每个部门前三高的工资,然后再连接部门表,一般我们找的是每个部门的最高薪资或者最低薪资,可以通过GroupBy和MAX、MIN函数求出,但这种求出前几的情况不是很好处理,下面我们介绍几种窗口函数(很重要) 常用窗口函数总结: 代码: SELECT emp.*,dept.* FROM emp JOIN dept on emp.DEPTNO = dept.DEPTNO
SELECT DEPTNO FROM emp GROUP BY DEPTNO HAVING count(*) >= 5
select emp.* FROM emp where sal>(SELECT SAL FROM emp where ENAME = 'SMITH')





SELECT ENAME,SAL FROM emp WHERE SAL in (SELECT DISTINCT SAL FROM emp WHERE DEPTNO = 30) AND DEPTNO < 30 

【注意】MySQL中对应日期计算的函数


SELECT dept.* ,count(ENAME) FROM emp right JOIN dept on emp.DEPTNO = dept.DEPTNO GROUP BY DEPTNO

SELECT ENAME,(SAL+IFNULL(COMM,0))*12 as YEARSsal FROM emp ORDER BY YEARSsal ASC

UPDATE emp SET SAL = SAL*1.1 WHERE (TIMESTAMPDIFF(YEAR,HIREDATE,NOW()))>30力扣SQL题解
score 降序返回结果表。
select b.Score from Scores b where b.Score >= X;select count(distinct b.Score) from Scores b where b.Score >= X as Rank;






