注意:查询时要根据逻辑一步一步来
[注:HAVING后的条件就是在GROUP BY分组执行后再执行的一个筛选(有些查询条件的执行可能在分组查询前后执行的)]
示例:
1.简单分组查询(查询每个部门的员工的最高工资)
SELECT MAX(salary),department_id FROM employees GROUP BY department_id;
2.根据department_id分组查询邮箱中包含x字符的平准工资
SELECT AVG(salary) FROM employees WHERE email LIKE '%x%' GROUP BY department_id;
3.根据department_id分组查询有两个员工以上的部门的员工个
SELECT COUNT(*),department_id FROM employees GROUP BY department_id HAVING COUNT(*)>2;
[
总结:
分组前的筛选:GROUP BY字句的前面 关键字where;
分组后的筛选:GROUP BY字句的后面 关键字having;
分组函数做条件,肯定是放在having语句中(也就是说条件能在分组前创建的就在where中写,如果条件只能在分组后
才能创建这个条件,那么就在having中写);
能用分组前筛选的,就优先考虑放在分组前筛选(性能问题);
支持单个字段,多个字段,表达式,函数分组;
***看比较难的问题是,一定要将此问题拆开,细分,一步一步累加的去解决细分后的问题;
]
1.先看图分析:
2.链接查询的sql92语法[
select 查询列表
from 表1 别名,表2 别名
where 链接条件
and 筛选条件
group by 分组
....
]
示例:
等值链接(查询员工表中员工对应的部门表中的部门名称)
SELECT first_name,department_name FROM employees,departments WHERE employees.department_id=departments.department_id;
3.链接查询的sql99语法[
select 查询列表
from 表1 别名 [链接类型:内连接:inner 左外链接left 右外链接right 全连接full 交叉链接cross]
join 表2 别名
on 链接条件
where 筛选条件
group by 分组
....
]
①.等值链接(inner可以省略)
SELECT first_name,department_name FROM employees INNER JOIN departments ON employees.department_id=departments.department_id;
②.多表内连接查询语法格式举例(inner可以省略)
select 查询列表
from 表1 别名1
inner join 表2 别名2 on 别名1.字段=别名2.字段
inner join 表3 别名3 on 别名1.字段=别名3.字段
where 筛选条件
group by 分组
....
③.外链接:应用场景:用于查询一个表中有,另一个表中没有的记录;
(查询locations表中site记录没有被departments引用的)
SELECT locations.location_id,site,departments.location_id
FROM locations
LEFT JOIN departments
ON locations.location_id=departments.location_id
WHERE departments.location_id IS NULL
④.全外链接在mysql中是不支持的,交叉链接不用;
①.分类
按子查询出现的位置
select后面:标量子查询
from后面:表子查询
where或having后面:标量子查询,列子查询,行子查询
exists后面:表子查询
按结果集的行列数不同
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)
婊子查询(结果集一般为多行多列)
特点:子查询要放在小刮号内;子查询一般放在条件的右侧;标量子查询一般搭配单行操作符(>,<,=...)使用了;列子查询一般搭配多行操作符(in,any/some,all)使用;
②.(where或having后面:标量子查询)查询员工工资大于‘李四’这个员工工资的所有员工
SELECT * FROM `employees` WHERE salary>(SELECT salary FROM employees WHERE first_name='李四');
③.(where或having后面:列子查询)查询departments表中部门名称为开发部或规划部的部门中的所有员工名称
SELECT first_name FROM employees WHERE department_id IN(
SELECT department_id FROM departments WHERE department_name IN('开发部','规划部')
);
④.(select后面:标量子查询)查询每个部门的员工个数
SELECT *,(SELECT COUNT(*) FROM employees WHERE employees.department_id=departments.department_id) number FROM departments;
⑤.(from后面:表子查询):就是把查询的结果集充当了一张表,然后为这张表去别名,然后去使用这张表;
⑥.(exists后面:表子查询):查询带有员工的部门名
SELECT d.department_name FROM departments d
WHERE EXISTS(
SELECT e.employee_id FROM employees e WHERE d.department_id=e.department_id
)
语法:查询语句+limit 起始的索引(不看id)[page],要显示的条目个数[pageSize];
page=(page-1)*要显示的条目个数
联合查询union:将多条查询语句查询的结果合并成一个结果;
语法:查询语句1 union 查询语句2 union 查询语句3 union ......
应用场景:查询的结果来自于多个表,且多个表没有直接的连接关系,但查询的信息一致时;
特点:使用union关键字默认是去重的,使用union all 可以不去重复;
要求多条查询语句的查询列数是一致;
要求多条查询语句查询的每一列的类型和顺序最好一致;