0


[mysql]子查询覆盖范围很广的练习题

答案如下

1查询和Zlotkey相同部门的员工姓名和工资

这里建议使用IN

SELECT last_name,salary FROM employees

WHERE department_id IN (SELECT department_id FROM

                employees

                WHERE last_name='Zlotkey')

2查询工资比公司平均工资高的员工的员工号,姓名和工资

SELECT department_id,last_name,salary

FROM employees

WHERE salary>(SELECT AVG(salary)

          FROM employees)

#3..选择工资大于所有JOB_ID = 'SA_MAN'的员工的工资的员工的last_name, job_id, salary

SELECT last_name, job_id, salary FROM employees

WHERE salary>ALL(SELECT salary FROM employees

WHERE job_id='SA_MAN')

#这里因为是使用大于所有,所以我们使用ALL关键词,而不是ANY关键词,因为ANY只要大于其中一个就可以.这里使用的是从外往里写的方法.

#4查询和姓名中包含字母u的员工在相同部门的员工的员工号和姓名

SELECT employee_id,last_name FROM employees

WHERE department_id IN (SELECT department_id FROM employees WHERE last_name LIKE '%u%')

#这里要注意部门是多个,所以我们要使用IN,

#5.查询在部门的location_id为1700的部门工作的员工的员工号

SELECT employee_id FROM employees

WHERE department_id IN (SELECT department_id FROM departments WHERE location_id=1700)

#这里2个点要注意,因为只出现在两个表里的字段,所以只需要一次多表查询,而如果出现了3个表的字段,就需要2次子查询,或者2次多表连接.并且记得用IN

#6查询管理者是King的员工姓名和工资

SELECT last_name,salary FROM employees

WHERE manager_id=(SELECT manager_id FROM employees

              WHERE last_name='king')

#这里自连接也可以完成,并且效率比子查询高.

#7查询工资最低的员工信息: last_name, salary

SELECT last_name, salary FROM employees

WHERE salary=(SELECT MIN(salary) FROM employees)

#只是为了引出下面的题目的题目

#8查询平均工资最低的部门信息

#方法1用三层子查询

SELECT * FROM departments WHERE department_id=(

SELECT department_id FROM employees GROUP BY department_id

HAVING AVG(salary)=(SELECT MIN(A_S) FROM (SELECT AVG(salary) A_S FROM employees GROUP BY department_id) ls))

#方法2使用ALL

SELECT department_id, AVG(salary) FROM employees

GROUP BY department_id

HAVING AVG(salary)<=ALL(SELECT AVG(salary) A_S FROM employees GROUP BY department_id)

#方法3使用ORDER BY和LIMIT

SELECT *

FROM departments

WHERE department_id = (

        SELECT department_id

        FROM employees

        GROUP BY department_id

        HAVING AVG(salary) = (

                     SELECT AVG(salary) avg_sal

                     FROM employees

                     GROUP BY department_id

                     ORDER BY avg_sal

                     LIMIT 0,1

                    )          

        )

#方式四:使用多表连接

SELECT T1.* FROM departments T1 JOIN

(SELECT department_id,AVG(salary) avg_sal FROM employees GROUP BY department_id) T2

ON T1.department_id=T2.department_id

ORDER BY avg_sal

LIMIT 0,1

#9.查询平均工资最低的部门信息和该部门的平均工资(相关子查询)

SELECT *,(SELECT AVG(salary) FROM employees e WHERE e.department_id=a.department_id ) A_G FROM departments a

WHERE department_id=(SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary)<=ALL(SELECT AVG(salary) FROM employees GROUP BY department_id))

#这题和上面的题目一样,只不过多个一列平均工资,要记得表名.*代表的就是查询全部字段

#10.查询平均工资最高的 job 信息

SELECT * FROM jobs

WHERE job_id=(SELECT job_id FROM employees GROUP BY job_id HAVING AVG(salary)>=ALL(SELECT AVG(salary) FROM employees GROUP BY job_id))

#方法2,不用ALL,使用ALL里面的表进行嵌套,查询这个字段的MAX平均工资.方法3,查询平均值表,对这个表进行降序排序,选择最大的平均工资.之后分流要么继续用子查询,要么用多表查询

#11.查询平均工资高于公司平均工资的部门有哪些

SELECT * FROM departments WHERE department_id IN

(SELECT department_id FROM employees GROUP BY department_id

HAVING AVG(salary)>(SELECT AVG(salary) FROM employees))

#这题因为是只要高于公司平均工资就可以,所以我们的最后一层子查询比较简单

#12.查询出公司中所有 manager 的详细信息

SELECT * FROM employees e

WHERE EXISTS(SELECT * FROM employees e2 WHERE e.employee_id=e2.manager_id)

#13.各个部门中 最高工资中最低的那个部门的 最低工资是多少?

SELECT MAX(salary) M_s FROM employees

GROUP BY department_id

ORDER BY M_s

LIMIT 0,1

#这题不得不吐槽一下mysql没有Oracle好用,Oracle可以直接嵌套聚合函数),这里可以用临时表,也可以用LIMIT.或者多表连接查询

#14.查询平均工资最高的部门的 manager 的详细信息: last_name, department_id, email, salary

SELECT last_name, department_id, email, salary FROM employees

WHERE department_id IN (SELECT manager_id FROM employees

WHERE department_id=(SELECT department_id FROM employees

GROUP BY department_id

HAVING AVG(salary)=(SELECT AVG(salary) A_s FROM employees

GROUP BY department_id

ORDER BY A_s

LIMIT 0,1)))

#15. 查询部门的部门号,其中不包括job_id是"ST_CLERK"的部门号

SELECT department_id FROM departments

WHERE department_id NOT IN (SELECT department_id FROM employees

WHERE job_id <>'ST_CLERK' AND department_id IS NOT NULL)

#这里要记得NOT IN中不能出现子查询的空值,因为空值是未知的,如果出现未知,未知包含一切,不包含未知,就是未知.什么玄学.IN是可以出现NULL.

#16. 选择所有没有管理者的员工的last_name

SELECT last_name FROM employees

WHERE manager_id IS NULL

#注意这里是要用子查询

SELECT last_name

FROM employees e1

WHERE NOT EXISTS (

SELECT *

FROM employees e2

WHERE e1.manager_id = e2.employee_id

);

#17.查询员工号、姓名、雇用时间、工资,其中员工的管理者为 'De Haan

SELECT employee_id,last_name, department_id, hire_date, salary FROM employees

WHERE manager_id=(SELECT employee_id FROM employees WHERE last_name='DE Haan')

#注意这里就是普通的子查询咯,主要考察的是你的脑壳对自连接的思路,也就是说这个人的管理者名字查出管理者的id,然后这个人的管理者id等于管理者id.我们再写一个EXISTS,注意EXISTS可以有多个条件用AND连接

SELECT employee_id,last_name, department_id, hire_date, salary FROM employees T1

WHERE EXISTS(SELECT * FROM employees T2 WHERE T2.last_name='DE Haan'AND T1.manager_id=T2.employee_id)

18.查询各部门中工资比本部门平均工资高的员工的员工号, 姓名和工资(难)

SELECT employee_id,last_name, salary

FROM employees T1

WHERE salary>

(SELECT AVG(salary) FROM employees T2

WHERE T1.department_id=T2.department_id

GROUP BY T2.department_id)

#这题标了一个难,我一会去看看为什么标难,还有方法2,那就是把每一行都加上部门的平均工资,然后直接自己和自己对比

SELECT employee_id,last_name, salary

FROM employees T1 JOIN

(SELECT department_id,AVG(salary) A_s FROM employees

WHERE department_id

GROUP BY department_id) table1 ON

T1.department_id=TABLE1.department_id

WHERE salary>A_s

#19.查询每个部门下的部门人数大于 5 的部门名称

SELECT department_name FROM departments T1

WHERE EXISTS ( SELECT 1 FROM employees T2

WHERE T1.department_id=T2.department_id

GROUP BY T2.department_id

HAVING COUNT(department_id)>5)

#脑子抽了一直想用EXISTS.不过也可行就是,每次都查询这个部门是否有大于5的情况.

SELECT department_name,department_id

FROM departments d

WHERE 5 < (

SELECT COUNT(*)

FROM employees e

WHERE d.`department_id` = e.`department_id`

);

#正解是这个,比较好理解,每次都查询该部门的人数,大于五就返回

#20查询每个国家下的部门个数大于 2 的国家编号

SELECT DISTINCT country_id FROM locations T1

WHERE 2<(SELECT count(*) FROM departments

WHERE location_id in (SELECT location_id FROM locations T2

WHERE T2.country_id=T1.country_id)

)

#我的思路是每个国家下面有多个地址,这些地址如果在部门表里有出现,错误的点是在哪呢,因为我以为每次只会运行一行,运行了第一行,比如第一行运行了,那么第一行的ID只会进去查找一个对应的部门.但是实际上是运行了第一行US,就会找到一个表里全部的部门,如果输入了一个国家比如US,那么这一个表US对应的几个部门id都会被拿去对比,所以我只要直接,令部门id相等就可以了

SELECT country_id

FROM locations l

WHERE 2 < (

SELECT COUNT(*)

FROM departments d

WHERE l.`location_id` = d.`location_id`

);

#这个才是正
标签: sql 数据库

本文转载自: https://blog.csdn.net/qq1021091799qq/article/details/143420213
版权归原作者 晴天qt01 所有, 如有侵权,请联系我们删除。

“[mysql]子查询覆盖范围很广的练习题”的评论:

还没有评论