MySQL操作系列之分组查询/链接查询/子查询/分页查询/联合查询(四)

(一).分组查询

注意:查询时要根据逻辑一步一步来

[: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 可以不去重复;       要求多条查询语句的查询列数是一致;       要求多条查询语句查询的每一列的类型和顺序最好一致;