MySQL分组查询、连表查询、子查询,分页查询
前言
之前讲过了MySQL的一些基本知识点,今天讲一点复杂的SQL语句!
MySQL相关知识点:
MySQL安装卸载以及使用
MySQL之账号管理,四大引擎以及DDL(数据定义语言)
MySQL常见查询、表达式、排序、分组查询基础
分组查询案例
语法:
select 查询列表 from 表 【where 筛选条件】
group by 分组的字段 【order by 排序的字段】;
特点:
1、和分组函数一同查询的字段必须是group by后出现的字段
2、筛选分为两类:分组前筛选和分组后筛选
针对的表 | 位置 | 连接的关键字 | |
---|---|---|---|
分组前筛选 | 原始表 | group by前 | where |
分组后筛选 | group by后的结果集 | group by后 | having |
配合组函数的分组:
1:查询每个工种的员工平均工资
SELECT AVG(salary),job_id FROM t_mysql_employees
GROUP BY job_id;
2:查询每个位置的部门个数
SELECT COUNT(*),location_id FROM t_mysql_departments
GROUP BY location_id;
我们还可以实现分组前的筛选:
1:查询邮箱中包含a字符的 每个部门的 最高工资
SELECT MAX(salary),department_id
FROM t_mysql_employees
WHERE email LIKE '%a%'
GROUP BY department_id;
2:查询有奖金的每个领导手下员工的平均工资
SELECT AVG(salary),manager_id
FROM t_mysql_employees
WHERE commission_pct IS NOT NULL
GROUP BY manager_id;
分组后筛选
1:查询哪个部门的员工 个数>5
SELECT COUNT(*),department_id
FROM t_mysql_employees
GROUP BY department_id
HAVING COUNT(*)>5;
2:每个工种有奖金的员工的 最高工资 >12000 的 工种编号和最高工资
SELECT job_id,MAX(salary)
FROM t_mysql_employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING MAX(salary)>12000;
添加排序:
每个工种有奖金的员工的 最高工资 >6000 的 工种编号和最高工资 ,按 最高工资升序
SELECT job_id,MAX(salary) m
FROM t_mysql_employees
WHERE commission_pct IS NOT NULL
GROUP BY job_id
HAVING m>6000
ORDER BY m ;
按多个字段分组:
查询每个工种每个部门的最低工资,并按最低工资降序
SELECT MIN(salary),job_id,department_id
FROM t_mysql_employees
GROUP BY department_id,job_id
ORDER BY MIN(salary) DESC;
连表查询
概念:
我们在很多项目中有时候需要的结果集在不同的表中,我们就需要用到连表查询。
分类
按年代分类:
sql92标准:仅仅支持内连接
sql99标准【推荐】:支持内连接+外连接(左外和右外)+交叉连接
按功能分类:
内连接:
等值连接
① 多表等值连接的结果为多表的交集部分
②n表连接,至少需要n-1个连接条件
③ 多表的顺序没有要求
④一般需要为表起别名
⑤可以搭配前面介绍的所有子句使用,比如排序、分组、筛选
非等值连接
自连接
外连接:
左外连接
右外连接
全外连接
交叉连接
连表查询这里涉及到一个名词笛卡尔集
,那么为什么会涉及到笛卡尔集呢?什么是笛卡尔集呢?
为什么会涉及到笛卡尔集?
因为连表查询如其名就是连着2或2以上张表查询结果集,这个结果集会将两(多)张表合二(多)为一,并且是1条数据连接完第二张表所有数据后第二条数据又会连接完第二张表的数据,这显然不是我们一般情况下需要的结果。
什么是笛卡尔集呢?
假设a表中有4条数据,b表中有14条数据,查询出来的就是4*14条数据,这个结果集就叫笛卡尔集。
笛卡尔集产生的条件:
– 省略连接条件
– 连接条件无效
– 所有表中的所有行互相连接
• 为了避免笛卡尔集, 可以在 WHERE 加入有效的连接条件。
连接
使用连接在多个表中查询数据
• 在 WHERE 子句中写入连接条件。
• 在表中有相同列时,在列名之前加上表名前缀
区分重复的列名
• 在不同表中具有相同列名的列可以用表的别名加以区分。
• 如果使用了表别名,则在select语句中需要使用表别名代替表名
• 表别名最多支持32个字符长度,但建议越少越好
连接多个表
• 连接 n个表,至少需要 n-1个连接条件。 例如:连接三个表,至少需要两个连接条件。
sql92标准连接查询案例
一、:等值连接
查询女神名和对应的男神名
SELECT NAME,boyName
FROM boys,beauty
WHERE beauty.boyfriend_id= boys.id;
查询员工名和对应的部门名
SELECT last_name,department_name
FROM t_mysql_employees,departments
WHERE t_mysql_employees.`department_id`=t_mysql_departments.`department_id`;
可以加筛选
查询有奖金的员工名、部门名
SELECT last_name,department_name,commission_pct
FROM t_mysql_employees e,t_mysql_departments d
WHERE e.`department_id`=d.`department_id`
AND e.`commission_pct` IS NOT NULL;
查询城市名中第二个字符为o的部门名和城市名
SELECT department_name,city
FROM t_mysql_departments t_mysql_d,locations l
WHERE d