分组查询(GROUP BY)
语法:
GROUP BY 分组条件
描述:
就像在分类一样。
举个例子,比如你现在有一些水果,里面有香蕉,有苹果,有橘子等等,我现在要把每个水果的数量搞错了,那这个GROUP BY 就像给你分好框,自己去数数量就好了。那这个SQL语句要怎么写呢。
SELECT 水果名称,水果数量
FROM 水果表
GROUP BY 水果名称
分组后查询(HAVING)
特点:
分组函数条件肯定是放在having子句中
能用分组前筛选的尽量在分组前筛
WHERE和HAVING的区别
where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,where条件中不能包含聚组函数,使用where条件过滤出特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件过滤出特定的组,也可以使用多个分组标准进行分组。
连接查询(JOIN ON)
99语法:
SELECT 要查询的内容
FROM 表名1
JOIN 表名2
ON 连接条件 表1.主键 = 表2.外键
连接类型:
连接类型
内连接 inner 重点
外连接 outer
左外 left outer 重点
右外 right outer 重点
左外连接:left join 左边的是主表
右外连接:right join 右边的是主表
全外 full outer
交叉连接 cross
案列1: 查询部门平均工资大于7000的部门名称
# 查询部门平均工资大于7000的部门名称
SELECT d.`department_name`
FROM `departments`d LEFT JOIN `employees`e
ON d.`department_id` = e.`department_id`
GROUP BY d.`department_id`
HAVING AVG(salary) > 7000;
案例2: 查询部门id大于50的部门分布在那个城市
# 查询部门id大于50的部门分布在那个城市
SELECT l.`city` ,d.`department_name`
FROM `locations`l LEFT JOIN `departments`d
ON l.`location_id` = d.`location_id`
WHERE `department_id` > 50;
查询会出现笛卡尔乘积的情况
笛卡尔乘积
表1表2 = 表1的行数表2的行数
出现原因:没有有效的连接条件
如果查询的字段来自不同的表,要用连接条件
子查询(难)
为什么要用子查询?
假如我要查询公司工资最少的员工名、工种编号和工资。要怎么写?
#先查询工资最低是什么
SELECT MIN(salary)
FROM employees;
# 然后把工资记起来2100
SELECT `first_name`,`job_id`,`salary`
FROM employees
WHERE salary = 2100;
我们这样写语法就很麻烦,于是就要用子查询
子查询怎么写呢?
# 把两个查询语句连接起来就好了。
SELECT `first_name`,`job_id`,`salary`
FROM employees
WHERE salary = (
SELECT MIN(salary)
FROM employees
);
子查询基本语法写法:
SELECT 需要查的东西
FROM 表1 JOIN 表2
ON 连接条件
WHERE 筛选条件 = (
SELECT 需要查的东西
FROM 表1 JOIN 表2
ON 连接条件
WHERE 筛选条件 =(
。。。
)
)
GROUP BY 分组条件
HAVING (
SELECT 需要查的东西
FROM 表1 JOIN 表2
ON 连接条件
WHERE 筛选条件 =(
。。。
)
)
ORDER BY 排序依据
LIMIT 分页查询
我觉得叫嵌套查询比较合适。
一个查询里面嵌套一个查询,一直套娃。
案例1:查询平均工资最低的部门信息和该部门的平均工资
#查询平均工资最低的部门信息和该部门的平均工资
SELECT *,AVG(salary)
FROM `departments`d LEFT JOIN `employees`e
ON d.`department_id` = e.`department_id`
WHERE e.`department_id` = (
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) =(
SELECT AVG(salary)
FROM employees
GROUP BY department_id
ORDER BY AVG(salary)
LIMIT 1
)
);
可能会看不懂
我们把这个例题分成三步来写
1、先查询最低平均工资
SELECT AVG(salary)
FROM employees
GROUP BY department_id
ORDER BY AVG(salary)
LIMIT 1
2、查询最低平均工资的部门ID
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) =(
SELECT AVG(salary)
FROM employees
GROUP BY department_id
ORDER BY AVG(salary)
LIMIT 1
)
3、查询平均工资最低的部门信息和该部门的平均工资
SELECT *,AVG(salary)
FROM `departments`d LEFT JOIN `employees`e
ON d.`department_id` = e.`department_id`
WHERE e.`department_id` = (
SELECT department_id
FROM employees
GROUP BY department_id
HAVING AVG(salary) =(
SELECT AVG(salary)
FROM employees
GROUP BY department_id
ORDER BY AVG(salary)
LIMIT 1
)
);