以组为操作单位,一组数据得到一个结果。
在没有手动分组的前提下,整张表默认为一组数据
max(列名):获取最大值
min(列名):获取最小值
sum(列名):获取总和
avg(列名):获取平均值
count(列名):统计值的个数
所有组函数都会自动忽略null值
-- 查看员工的最高薪资 select max(salary) from employees -- 查看员工的最低薪资、平均薪资、月薪资总和 select min(salary),avg(salary),sum(salary) from employees -- 统计总共有多少名员工 select count(*) from employees select count(employee_id) from employees -- 统计员工表中部门的个数 -- 先对整张表的部门id进行去重,再count统计结果 select count(distinct department_id) from employees
在某些情况下,我们需要根据需要对表中数据进行手动分组
规则:值相同的为同一组数据
select 列名 from 表名 group by 列名
执行顺序:from-->group by-->select
先确定从哪张表进行操作-->对表中数据进行分组-->基于分组结果进行查询操作
-- 查询各个部门的平均薪资 select department_id,avg(salary) from employees group by department_id
先where,再group by
先筛选出符合要求的数据,再对符合要求的数据进行分组时,分组的工作量会被减少,效率更高
where 条件 group by 列名
-- 查询部门id为10,20,30的部门的平均薪资 select department_id,avg(salary) from employees where department_id in(10,20,30) group by department_id
执行顺序:from-->where-->group by-->select
和where类似,也是用来做数据筛选,在分组之后执行
group by 列名 having 条件
-- 查询部门平均薪资>=7000的部门id select department_id,avg(salary) from employees group by department_id -- 先分组 having avg(salary)>=7000 -- 后筛选
where在分组前执行,having在分组后执行
where子句存在分组时不能使用组函数,但是having可以
当既可以使用where,又能使用having时,优先使用where,效率更高
作用:限制查询结果显示的条目数,通常用于分页
select 列名.. from 表名 limit 显示的起始下标,显示的条数
使用:
该关键字是基于查询的最终结果进行限制显示,所以其与其他查询关键字使用时,必须最后执行,所以一定写在最后
下标为0时,可以省略不写
-- 查询工资最高的前十名员工信息 select employee_id,salary from employees order by salary desc -- 先根据工资进行降序排序 limit 0,10 -- 显示前十行 -- 查看前十条员工信息 select * from employees limit 10 -- 查询部门平均薪资最高的前3个部门id -- 分析: -- 部门平均薪资:根据部门id分组 group by -- 最高:根据平均薪资进行降序排序 order by avg(salary) -- 前三个:limit从最终查询结果中提取出前三条 select department_id,avg(salary) from employees group by department_id -- 根据部门id分组 order by avg(salary) desc -- 根据平均薪资进行降序排序 limit 3 -- 从最终查询结果中提取出前三条
select 、 from 、where 、 order by 、 group by 、 having 、 limit
语法顺序: select 、 from 、where、 group by、having 、order by 、limit
当一个SQL的执行需要借助另一个SQL的执行结果时,则需要进行SQL嵌套,该语法结构称之为子查询
select 列名... from 表名 where 列名 =|in (子SQL语句)
执行顺序:优先执行小括号内的子SQL,根据子SQL的执行结果再执行外层SQL
只要逻辑完整,对SQL的嵌套层数不做要求
执行:从内向外执行
子SQL(被嵌套的SQL)返回的时一行一列的单个结果
-- 查询员工id为101号员工的领导信息 -- 先查询员工id为101号员工的直接领导的id select manager_id from employees where employee_id=101 -- 拼装 select * from employees where employee_id=(select manager_id from employees where employee_id=101 ) -- 查询员工id为100的员工所在的部门信息 -- 查询员工id为100的员工所在的部门id select department_id from employees where employee_id=100 -- 拼装 select * from departments where department_id =(select department_id from employees where employee_id=100)
子SQL返回的是多个结果
-- 查询工资>10000的员工所在的部门信息 select * from departments where department_id in(select department_id from employees where salary>10000)
将子SQL的查询结果临时看作一张表进行后续操作
为了符合语法要求,需要给子查询的结果起别名充当临时表的表名
-- 查询工资最高的前十名员工的总薪资 -- 分析:1. 把工资最高的前十名员工的薪资查出来 -- 2. 对这十个工资进行求和 -- 查询SQL的基本语法:select 列名 from 表名 select sum(salary) from (select salary from employees order by salary desc limit 10) as e -- 子SQL:把工资最高的前十名员工的薪资查出来 select salary from employees order by salary desc limit 10
关系字段:两表中有关联关系的字段
什么是表连接?
当我们的查询结果需要从多张表中获取时,此时应该让表之间建立连接,同时获取数据
特点:同时对连接双方做约束,双方只有符合连接条件的数据才会进行显示
select 表名.列名, 表名.列名,... from 表名1 inner join 表名2 on 连接条件 -- 两表间的关系字段
-- 查询员工的id、工资与部门名称 -- 第一步:确定数据来自于哪些表 -- 第二步:确定两表之间的关系字段 -- 书写表连接完成查询操作 select e.employee_id 员工id,e.salary 员工工资,d.department_name -- 基于连接结果进行查询操作 from employees e inner join departments d -- 起别名,方便后续书写 on e.department_id=d.department_id -- 关系字段:员工表的部门id=部门表的部门id
from-->join on:确定数据来源
select:查询操作
特点:左表中的数据无论如何都会显示,右表中的数据只有符合连接条件才会显示
select 表名.列名, 表名.列名,... from 左表 left outer join 右表 on 连接条件 -- 两表间的关系字段
-- 使用左外连接显示员工信息及其部门信息 select e.*,d.* from employees e left outer join departments d -- 员工信息无论如何都会显示,部门信息符合连接条件才会显示 on e.department_id=d.department_id
特点:右表中的数据无论如何都会显示,左表中的数据只有符合连接条件才会显示
select 表名.列名, 表名.列名,... from 左表 right outer join 右表 on 连接条件 -- 两表间的关系字段
-- 使用右外连接显示部门信息及对应员工信息 select e.*,d.* from employees e right outer join departments d on e.department_id=d.department_id
连接关键字中的inner、outer可以省略
特点:对双方都不做约束
作用:将两个查询结果进行合并
查询结果1 union 查询结果2
使用:
合并双方字段数目、内容必须一致
union关键字可以去重
union all 不会对结果去重
-- 查询员工表所有信息 select employee_id,first_name,salary from employees union all -- 合并,不去重 -- 查询员工表所有信息 select employee_id,first_name,salary from employees
特点:是特殊的表连接,参与连接的是同一张表
使用:
表中的两个字段为关系字段,作为连接条件
-- 按照指定要求查询员工信息:员工id,员工姓名,直接领导的id,直接领导的姓名 select e1.employee_id 员工id,e1.first_name 员工姓名,e1.manager_id 领导id,e2.first_name 领导姓名 from employees e1 left join employees e2 -- e1:员工信息 e2:领导信息 on e1.manager_id=e2.employee_id -- 连接条件:员工的领导id=领导的员工id
连接双方判断同一字段,作为连接条件
-- 查询工资相同的员工id及其工资 select e1.employee_id,e1.salary,e2.employee_id,e2.salary from employees e1 left join employees e2 -- 连接参与比较的两个员工 on e1.salary=e2.salary -- 两个员工的工资相同 where e1.employee_id>e2.employee_id
如果查询字段来自于多张表,内连接或左外连接
如果查询字段来自于一张表并且来自同一行数据,则简单查询|子查询
如果查询字段来自于一张表但是不来自于同一行数据。则自连接
特点:同时从多张表中获取数据
select 表名.列名, 表名.列名,... from 表1 left join 表2 on 连接条件 -- 表1和表2的关系字段 left join 表3 on 连接条件 -- 表1和表3的关系字段|表2和表3的关系字段
-- 查询员工id,员工姓名,所属部门id,部门名称,部门所在城市 select e.employee_id,e.first_name,d.department_id,d.department_name,l.city from employees e left join departments d -- 先让员工表和部门表建立连接 on e.department_id=d.department_id -- 员工的部门id=部门的id left join locations l -- 再让地址表参与连接 on d.location_id=l.location_id -- 部门表的地址id=地址表的id
实际开发中,不建议表连接超过3张表,否则会有性能问题