DQL练习
1. 判断输出结果是否相同
#不同
SELECT * FROM employees;#输出全部员工信息
SELECT
*
FROM
employees
WHERE `commission_pct` LIKE '%%'
AND last_name LIKE '%%' ;
#通配符不能代表null,因此commission_pct为null的员工信息不会被筛选出来
2. 子查询经典案例
#1.查询工资最低的员工信息
SELECT
*
FROM
employees
WHERE salary =
(SELECT
MIN(salary)
FROM
employees) ;
#2.查询平均工资最低的部门信息
#(1)查询各部门的平均工资
SELECT
AVG(salary),
department_id
FROM
employees
GROUP BY department_id ;
#(2)查询(1)中的最低平均工资
SELECT
MIN(ag)
FROM
(SELECT
AVG(salary) ag,
department_id
FROM
employees
GROUP BY department_id) ad_dep ;
#(3)查询哪个部门的平均工资等于(2)
SELECT
AVG(salary),
department_id
FROM
employees
GROUP BY department_id
HAVING AVG(salary) =
(SELECT
MIN(ag)
FROM
(SELECT
AVG(salary) ag,
department_id
FROM
employees
GROUP BY department_id) ad_dep) ;
#(4)根据(3)查询到的部门编号查询部门信息
SELECT
*
FROM
departments
WHERE department_id =
(SELECT
department_id
FROM
employees
GROUP BY department_id
HAVING AVG(salary) =
(SELECT
MIN(ag)
FROM
(SELECT
AVG(salary) ag,
department_id
FROM
employees
GROUP BY department_id) ad_dep)) ;
#---------------------------------------
/*
简单方法:
将部门分组之后,按照平均工资由低到高排序,
则第一条数据的department_id就是平均工资最低的部门id,
之后再查询部门详细信息即可
*/
SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0, 1 ;
#查询部门详细信息
SELECT
*
FROM
departments
WHERE department_id =
(SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0, 1) ;
#3.查询平均工资最低的部门信息和该部门的平均工资
#(1)将各部门分组,按平均工资升序排序,第一条数据就是平均工资最低的部门id
SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0, 1 ;
#(2)查询部门号为(1)的部门信息和平均工资
SELECT
d.*,
AVG(salary)
FROM
departments d
INNER JOIN employees e
ON d.`department_id` = e.`department_id`
WHERE d.`department_id` =
(SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0, 1) ;
#--------------------------------
SELECT
d.*,
ag_dep.ag
FROM
departments d
INNER JOIN
(SELECT
AVG(salary) ag,
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0, 1) ag_dep
ON d.`department_id` = ag_dep.`department_id` ;
#4.查询平均工资最高的job信息
#(1)查询平均工资最高的job_id
SELECT
job_id
FROM
employees
GROUP BY job_id
ORDER BY AVG(salary) DESC
LIMIT 1 ;
#(2)查询job_id等于(1)的job信息
SELECT
*
FROM
jobs
WHERE job_id =
(SELECT
job_id
FROM
employees
GROUP BY job_id
ORDER BY AVG(salary) DESC
LIMIT 1) ;
#5.查询平均工资高于公司平均工资的部门有哪些
#(1)查询工资的平均工资
SELECT
AVG(salary)
FROM
employees ;
#(2)查询平均工资高于(1)的部门id
SELECT
department_id
FROM
employees
GROUP BY department_id
HAVING AVG(salary) >
(SELECT
AVG(salary)
FROM
employees) ;
#(3)查询平均工资高于(1)的部门信息
SELECT
*
FROM
departments
WHERE department_id IN
(SELECT
department_id
FROM
employees
GROUP BY department_id
HAVING AVG(salary) >
(SELECT
AVG(salary)
FROM
employees)) ;
#6.查询公司中所有manager的详细信息
SELECT
*
FROM
employees
WHERE employee_id IN
(SELECT
DISTINCT manager_id
FROM
employees) ;
#7.各个部门中,最高工资最低的那个部门的最低工资是多少
#(1)查询各个部门的最高工资,按升序排后取第一条数据,即可得到最高工资中最低的那个部门的id
SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY MAX(salary) ASC
LIMIT 1 ;
#(2)查询(1)部门的最低工资
SELECT
department_id,
MIN(salary)
FROM
employees
WHERE department_id =
(SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY MAX(salary) ASC
LIMIT 1) ;
#8.查询平均工资最高的部门的manager的详细信息:last_name, department_id, email, salary
#(1)查询平均工资最高的部门的id
SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
LIMIT 0, 1 ;
#(2)查询(1)部门的manager信息
SELECT
e.last_name,
d.department_id,
e.email,
e.salary
FROM
departments d
INNER JOIN employees e
ON d.`manager_id` = e.`employee_id`
WHERE d.`department_id` =
(SELECT
department_id
FROM
employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
LIMIT 0, 1) ;
3. 综合练习
#1.查询每个专业的学生人数
SELECT
majorid,
COUNT(*)
FROM
student
GROUP BY majorid ;
#2.查询每个学生的平均分、最高分
SELECT
studentno,
AVG(score),
MAX(score)
FROM
result
GROUP BY studentno ;
#3.查询姓张的学生中最低分大于60的学生的学号、姓名
SELECT
s.studentno,
s.studentname
FROM
student s
INNER JOIN result r
ON s.`studentno` = r.`studentno`
WHERE studentname LIKE '张%'
GROUP BY s.studentno
HAVING MIN(score) > 60 ;
#-------------------------------------
SELECT
s.studentno,
studentname
FROM
student s
INNER JOIN
(SELECT
MIN(score) m_s,
studentno
FROM
result
GROUP BY studentno) min_res
ON s.`studentno` = min_res.studentno
WHERE s.`studentname` LIKE '张%'
AND min_res.m_s > 60 ;
#4.查询生日在“1988-1-1”后的学生姓名、专业名称
SELECT
s.studentname,
m.majorname
FROM
student s
INNER JOIN major m
ON s.`majorid` = m.`majorid`
WHERE DATEDIFF(s.`borndate`, '1988-1-1') > 0 ;
#5.查询每个专业的男生人数和女生人数分别是多少
SELECT
majorid 专业,
sex 性别,
COUNT(*) 人数
FROM
student
GROUP BY majorid,
sex ;
#----------------
SELECT
majorid,
(SELECT
COUNT(*)
FROM
student
WHERE sex = '男'
AND majorid = s.majorid) 男生,
(SELECT
COUNT(*)
FROM
student
WHERE sex = '女'
AND majorid = s.majorid) 女生
FROM
student s
GROUP BY majorid ;
#6.查询专业和张翠山一样的学生的最低分
SELECT
MIN(score)
FROM
result r
INNER JOIN student s
ON r.`studentno` = s.`studentno`
WHERE s.`majorid` =
(SELECT
majorid
FROM
student
WHERE studentname = '张翠山') ;
#7.查询大于60分的学生的姓名、密码、专业名
SELECT
s.studentname,
loginpwd,
majorname
FROM
student s
INNER JOIN major m
ON s.`majorid` = m.`majorid`
INNER JOIN result r
ON s.`studentno` = r.`studentno`
WHERE r.`score` > 60 ;
#8.按邮箱位数分组,查询每组的学生个数
SELECT
LENGTH(email),
COUNT(*)
FROM
student
GROUP BY LENGTH(email) ;
#9.查询学生名、专业名、分数
SELECT
s.studentname,
majorname,
score
FROM
student s
INNER JOIN major m
ON s.`majorid` = m.`majorid`
LEFT JOIN result r
ON s.`studentno` = r.`studentno` ;
#10.查询哪个专业没有学生,分别用左连接和右连接实现
SELECT
majorname
FROM
major m
LEFT JOIN student s
ON m.`majorid` = s.`majorid`
WHERE s.studentno IS NULL ;
#-------------------------------
SELECT
majorname
FROM
student s
RIGHT JOIN major m
ON m.`majorid` = s.`majorid`
WHERE s.studentno IS NULL ;
#11.查询没有成绩的学生人数
SELECT
COUNT(*)
FROM
student s
LEFT JOIN result r
ON s.`studentno` = r.`studentno`
WHERE r.`id` IS NULL ;