四、MySQL分页查询 + 子查询复习 学习笔记 (复习连接查询相关内容 详解)

8:分页查询

应用场景:当要显示的数据,一页显示不全,需要分页提交sql请求
语法:
SELECT 查询列表
FROM 表名
【JOIN type JOIN 表2
ON 连接条件
WHERE 筛选条件
GROUP BY 分组字段
HAVING 分组后的筛选
ORDER BY 排序的字段】
LIMIT 要显示条目的起始索引(起始索引从0开始),长度(要显示的条目个数)

特点:
1.LIMIT 语句放在查询语句的最后
2.上述代码的执行顺序为:
1)FROM 表名
2)JOIN type JOIN 表2
3)ON 连接条件
4)WHERE 筛选条件
5)GROUP BY 分组字段
6)HAVING 分组后的筛选
7)SELECT 查询列表
8)ORDER BY 排序的字段
9)LIMIT 要显示条目的起始索引(起始索引从0开始),长度(要显示的条目个数)

3.公式
要显示的页数page , 每页的条目数size
SELECT 查询列表
from 表名
LIMIT (page-1)*size,size;

				   page    				 第n页的起始索引
				     1							 0
				     2							10
				     3							20
# 【案例1】 查询前五条员工信息
SELECT * FROM employees LIMIT 0,5;
# 默认起始索引从0开始,可省略不写
SELECT * FROM employees LIMIT 5;

# 【案例2】 查询第11条到第25条员工信息
SELECT * FROM employees LIMIT 10,15;

# 【案例3】 有奖金的员工信息,并且工资较高的前10名显示出来
SELECT * FROM employees 
WHERE commission_pct IS NOT NULL 
ORDER BY salary DESC 
LIMIT 10;

# 【练习1】 查询所有学员的邮箱的用户名
SELECT SUBSTR(email,1,INSTR(email,'@')-1) 用户名
FROM stuinfo

# 【练习2】 查询男生和女生的个数
SELECT count(*) 个数 
FROM stuinfo
GROUP BY sex;

# 【练习3】 查询年龄 > 18岁的所有学生的姓名和年级名称
SELECT name, gradeName
FROM stuinfo s
INNER JOIN grade g
on s.gradeId = g.id
WHERE age >18;

# 【练习4】 查询哪个年级的最小年龄大于20岁
# 1) 查询每个年级的最小年龄
SELECT MIN(age),gradeid
FROM stuinfo
GROUP BY gradeId;

# 2) 1)的查询结果中大于20岁的
SELECT MIN(age),gradeid
FROM stuinfo
GROUP BY gradeId
HAVING MIN(age) > 20;

子查询复习:

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

# 1) 查询最低工资
SELECT MIN(salary)
FROM employees;

USE myemployees;
# 2) 查询last_name,salary,要求last_name = 1)中的查询结果
SELECT last_name , salary
FROM employees
WHERE salary = (
				SELECT MIN(salary)
				FROM employees
);

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

# 方法一:
# 1)查询各部门的平均工资
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;

# 2) 查询 1)结果上的最低平均工资
SELECT MIN(ag),department_id
FROM (
				SELECT AVG(salary) ag,department_id
				FROM employees
				GROUP BY department_id 
) ag_dep

# 3) 查询哪个部门的平均工资 = 2)查询出来的结果
SELECT AVG(salary) ag,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 
											) ag_dep
);

# 4) 查询部门编号 = 3)的查询结果中的部门编号的  部门信息
SELECT d.*
FROM departments d
WHERE d.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 
																							) ag_dep
												)
);

# 方法二:
# 1)查询各部门的平均工资
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;

# 2) 在 1) 的基础上升序排列,取第一条记录,就能得到平均工资最低的部门的编号
SELECT department_id
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0,1;

# 3)查询部门信息
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)查询各部门的平均工资
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;

# 2) 在 1) 的基础上升序排列,取第一条记录,就能得到平均工资最低的部门的编号
SELECT AVG(salary) , department_id
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) ASC
LIMIT 0,1;

# 3)查询部门信息(内连接)
SELECT d.* , 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)查询各部门的平均工资
SELECT AVG(salary) ag,department_id
FROM employees
GROUP BY department_id;

# 2) 在 1) 的基础上降序排列,取第一条记录,就能得到平均工资最低的工种的编号
SELECT AVG(salary) , job_id
FROM employees
GROUP BY job_id
ORDER BY AVG(salary) DESC
LIMIT 0,1;

# 3) 在2)的基础上,筛选出 job_id = 2)查询结果中的job_id
SELECT *
FROM jobs
WHERE job_id = (
				SELECT job_id
				FROM employees
				GROUP BY job_id
				ORDER BY AVG(salary) DESC
				LIMIT 0,1
);

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

# 1) 查询各个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id;

# 2) 查询整个公司的平均工资
SELECT AVG(salary)
FROM employees;

# 3) 筛选 2)的结果集,满足平均工资 > 1)
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) > (
				SELECT AVG(salary)
				FROM employees
);


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

# 1) 查询出所有的manager_id
SELECT DISTINCT manager_id
FROM employees;
 

# 2) 查询详细信息,满足employee_id =  1)中查询的结果
# 方法一
SELECT *
FROM employees
WHERE employee_id = ANY(
				SELECT DISTINCT manager_id
				FROM employees
);

# 方法二
SELECT *
FROM employees
WHERE employee_id in(
				SELECT DISTINCT manager_id
				FROM employees
);

 
#7.查询各个部门的最高工资中最低的 那个部门的 最低工资是多少
# 1) 查询各个部门的最高工资 中,最低的那个部门的最高工资
SELECT MAX(salary),department_id
FROM employees
GROUP BY department_id
ORDER BY MAX(salary) ASC
LIMIT 0,1;

# 2) 查询 1) 结果的那个部门的最低工资
SELECT MIN(salary)
FROM employees
WHERE department_id = (
			SELECT department_id
			FROM employees
			GROUP BY department_id
			ORDER BY MAX(salary) ASC
			LIMIT 0,1
);



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

# 1) 查询各个部门的平均工资
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id;

# 2) 在 1)的查询结果中,查找平均工资最高的部门的department_id
SELECT AVG(salary),department_id
FROM employees
GROUP BY department_id
ORDER BY AVG(salary) DESC
LIMIT 0,1;

# 3) 将employees 和 departments连接查询,筛选条件是 1)
SELECT last_name,d.department_id,email,salary
FROM employees e
INNER JOIN departments d
ON e.employee_id = d.manager_id
WHERE e.department_id = (
				SELECT department_id
				FROM employees
				GROUP BY department_id
				ORDER BY AVG(salary) DESC
				LIMIT 0,1
);

强化练习:

-- 一、查询每个专业的学生人数
SELECT majorid , COUNT(*)
FROM student
GROUP BY majorid;

-- 二、查询参加考试的学生中,每个学生的平均分、最高分
SELECT AVG(score) , MAX(score) , studentno
FROM result
GROUP BY studentno;

-- 三、查询姓张的每个学生的最低分大于60的学号、姓名
SELECT MIN(score),s.studentname,s.studentno
FROM student s
INNER JOIN result r
ON s.studentno = r.studentno
WHERE studentname LIKE'张%'
GROUP BY studentno
HAVING MIN(score) > 60;



-- 四、查询专业生日在“1988-1-1”后的学生姓名、专业名称
SELECT s.studentname , s.majorid, m.majorname,s.borndate
FROM student s
INNER JOIN major m
ON s.majorid = m.majorid
WHERE DATEDIFF(borndate,'1988-1-1')>0;


-- 五、查询每个专业的男生人数和女生人数分别是多少
# 方法一
SELECT COUNT(*) 个数, sex , majorid
FROM student
GROUP BY sex , majorid

# 方法二
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;

-- 六、查询专业和张翠山一样的学生的最低分

# 1) 查询张翠山的专业编号
SELECT majorid
FROM student
WHERE studentname = '张翠山';

# 2) 查询专业编号 =  1)的所有学生的编号
SELECT studentno
FROM student
WHERE majorid = (
				SELECT majorid
				FROM student
				WHERE studentname = '张翠山'
);
# 3) 查询最低分
SELECT MIN(score)
FROM result
WHERE studentno in (
					SELECT studentno
					FROM student
					WHERE majorid = (
									SELECT majorid
									FROM student
									WHERE studentname = '张翠山'
					)
);





-- 七、查询大于60分的学生的姓名、密码、专业名
SELECT s.studentname , s.studentno , r.score , loginpwd , majorname 
FROM student s
INNER JOIN result r
ON s.studentno = r.studentno
INNER JOIN major m
ON s.majorid = m.majorid
WHERE score > 60;


-- 八、按邮箱位数分组,查询每组的学生个数
SELECT COUNT(*) , LENGTH(email)
FROM student
GROUP BY LENGTH(email);

-- 九、查询学生名、专业名、分数
SELECT studentname , m.majorid , majorname , score
FROM student s
left JOIN result r
ON s.studentno = r.studentno
INNER JOIN major m
ON s.majorid = m.majorid;


-- 十、查询哪个专业没有学生,分别用左连接和右连接实现
# 左连接
SELECT m.majorid , m.majorname , s.studentno
FROM major m
LEFT JOIN student s
ON m.majorid = s.majorid
WHERE studentno IS NULL;

# 右连接
SELECT m.majorid , m.majorname , s.studentno
FROM student s
RIGHT JOIN major m
ON m.majorid = s.majorid
WHERE studentno IS NULL;



-- 十一、查询没有成绩的学生人数
SELECT COUNT(*) 无成绩学生个数
FROM student s
LEFT JOIN result r
ON s.studentno = r.studentno
WHERE r.id IS NULL;

你可能感兴趣的:(数据库)