MySQL基础关键_005_DQL(四)

目 录

一、分组函数

1.说明

2.max/min

3.sum/avg/count

二、分组查询

1.说明

2.实例

(1)查询岗位和平均薪资

(2)查询每个部门编号的不同岗位的最低薪资

3.having

(1)说明

[(2)查询除部门编号为 20,其余部门的平均薪资。](#(2)查询除部门编号为 20,其余部门的平均薪资。)

[(3)计算每个部门平均薪资,查询平均薪资 2000 以上的部门](#(3)计算每个部门平均薪资,查询平均薪资 2000 以上的部门)

4.组内排序

[(1)利用 substring_index 截取字串](#(1)利用 substring_index 截取字串)

[(2)利用 group_concat 拼接字符串](#(2)利用 group_concat 拼接字符串)

(3)查询每个职位薪资最高的两个员工

[三、单表 DQL 执行次序总结](#三、单表 DQL 执行次序总结)

四、连接查询

1.说明

2.笛卡尔积

3.内连接

(1)等值连接

(2)非等值连接

(3)自连接

4.外连接

(1)左外连接(左连接)

[(2)右外连接 (右连接)](#(2)右外连接 (右连接))

5.全连接

6.多表连接查询


一、分组函数

1.说明

  1. 执行原则:先分组,然后对每一组执行分组函数。若没有 group by 分组语句,整张表数据自成一组;
  2. 分组函数也称多行处理函数,因为有多个输入,一个输出;
  3. 分组函数自动忽略 null
  4. 因为执行次序,from --> where --> group by --> select --> order by。所以分组函数不能用于 where 之后;
  5. 以下分组函数可以组合使用

2.max/min

查询员工的最高薪资和最低薪资。

sql 复制代码
# 最高薪资
select max(salary) from employees;

# 最低薪资
select min(salary) from employees;

3.sum/avg/count

  • 查询全体员工的总薪资、平均薪资;
  • 查询总员工数、有津贴的员工数。
sql 复制代码
# 总薪资
select sum(salary) from employees;

# 平均薪资
select avg(salary) from employees;

# 总员工数
select count(emp_no) from employees;

# 有津贴的员工数
select count(commission) from employees;
  1. count(*) 和 count(1) 都是统计该组中总记录行数,效果一致;
  2. count(字段) 统计的是该字段中不为 null 的总个数。

二、分组查询

1.说明

  1. 语法格式:【group by 字段1, 字段2, 字段3......】;
  2. group by 的执行次序是在 where 之后;
  3. 当 select 语句中存在 group by ,则 select 后只能有 参加分组的字段分组函数

2.实例

(1)查询岗位和平均薪资

sql 复制代码
select job_title, avg(salary) from employees group by job_title;

(2)查询每个部门编号的不同岗位的最低薪资

sql 复制代码
select dept_no, job_title, min(salary) from employees group by dept_no, job_title;

3.having

(1)说明

  1. having 在 group by 之后,可以对分组之后的数据进行过滤;
  2. 只有存在 group by,才能使用 having
  3. 区别 where 过滤:where 是在分组之前过滤;
  4. 尽量使用 where 过滤,也就是越早过滤越好

(2)查询除部门编号为 20,其余部门的平均薪资。

sql 复制代码
# having
select dept_no, avg(salary) from employees group by dept_no having dept_no != 20;

# where(效率高,尽量使用)
select dept_no, avg(salary) from employees where dept_no != 20 group by dept_no;

(3)计算每个部门平均薪资,查询平均薪资 2000 以上的部门

sql 复制代码
select dept_no, avg(salary) from employees group by dept_no having avg(salary) > 2000;

4.组内排序

(1)利用 substring_index 截取字串

sql 复制代码
select substring_index('I Miss You! I Miss You! I Miss You!', '!', 1);
-- 截取到第一次出现"!"的位置

(2)利用 group_concat 拼接字符串

sql 复制代码
select group_concat('I ', 'Love ', 'You!');

(3)查询每个职位薪资最高的两个员工

sql 复制代码
select substring_index(group_concat(emp_name, salary order by salary desc), ',', 2) from employees group by job_title; 

三、单表 DQL 执行次序总结

  1. from;
  2. where;
  3. group by;
  4. having;
  5. select;
  6. order by。

四、连接查询

1.说明

  1. 从一张表中查数据称为单表查询。从两张以上的表查数据称为多表查询、连接查询;
  2. 分类
    1. 语法出现时间
      1. SQL 92(较少使用);
      2. SQL 99。
    2. 连接方式
      1. 内连接:
        1. 等值连接;
        2. 非等值连接;
        3. 自连接。
      2. 外连接:
        1. 左外连接;
        2. 右外连接。
      3. 全连接(MySQL 不支持)。

2.笛卡尔积

  1. 当两张表进行连接查询时,若没有任何条件进行过滤,最终的查询结果是两张表数据条数的乘积,这就是笛卡尔积;
  2. 为了避免笛卡尔积现象的发生,就需要添加条件进行过滤;
  3. 但是,添加条件进行过滤后,匹配的次数并没有减少
  4. 为提高执行效率和语句的可读性,建议为表起别名

3.内连接

查询两张表中满足条件的记录,即 求两张表的交集

(1)等值连接

  • 连接时,条件为等量关系;
  • 实例: 查询所有员工所在的部门、职位。
sql 复制代码
select e.emp_name, e.job_title, d.dept_name from employees e inner join departments d on e.dept_no = d.dept_no;

-- inner 可以省略不写
select e.emp_name, e.job_title, d.dept_name from employees e join departments d on e.dept_no = d.dept_no;

(2)非等值连接

  • 连接时,条件是非等量关系;
  • 实例:查询每个员工的姓名、薪资、薪资等级。
sql 复制代码
select e.emp_name, e.salary, s.grade from employees e join salary_grades s on e.salary between s.min_salary and s.max_salary;

(3)自连接

  • 连接时,一张表看作是两张表,自己和自己连接;
  • 实例: 查询每个员工的姓名、直属领导姓名。
sql 复制代码
select ee.emp_name as employee_name, er.emp_name as employer_name from employees ee join employees er on ee.manager_id = er.emp_no;

4.外连接

  1. 内连接是满足条件的记录,两张表的交集;
  2. 外连接是除了查询出满足条件的记录,再将其中的一张表的记录全部查询出来,若另一张表没有与之匹配的记录,则自动模拟 null 与之匹配
  3. 任何一个左连接都可以写成右连接,反之亦然

(1)左外连接(左连接)

查询所有部门信息,并找出每个部门下的员工。

sql 复制代码
select d.*, e.emp_name from departments d left outer join employees e on d.dept_no = e.dept_no;

-- outer 可以省略不写
select d.*, e.emp_name from departments d left join employees e on d.dept_no = e.dept_no;

(2)右外连接 (右连接)

查询所有员工以及该员工的直属领导。

sql 复制代码
select ee.emp_name employee_name, er.emp_name employer_name from employees er right join employees ee on ee.manager_id = er.emp_no;

5.全连接

  1. 将两张表数据全部查询出来,没有匹配记录则各自为对方模拟 null 进行匹配;
  2. MySQL 不支持,Oracle 支持。

6.多表连接查询

查询员工姓名、部门名称、薪资等级。

sql 复制代码
select e.emp_name, d.dept_name, s.grade from employees e join departments d on e.dept_no = d.dept_no join salary_grades s on e.salary between s.min_salary and s.max_salary;
相关推荐
花好月圆春祺夏安15 分钟前
基于odoo17的设计模式详解---装饰模式
数据库·python·设计模式
A__tao19 分钟前
SQL 转 Java 实体类工具
java·数据库·sql
m0_6530313632 分钟前
腾讯云认证考试报名 - TDSQL数据库交付运维专家(TCCE PostgreSQL版)
运维·数据库·腾讯云
叁沐1 小时前
MySQL 06 全局锁和表锁:给表加个字段怎么有这么多阻碍?
mysql
小马哥编程1 小时前
【iSAQB软件架构】架构决策记录-ADR
数据库·架构·系统架构·设计规范
萧鼎2 小时前
深度探索 Py2neo:用 Python 玩转图数据库 Neo4j
数据库·python·neo4j
m0_653031362 小时前
腾讯云认证考试报名 - TDSQL数据库交付运维专家(TCCE MySQL版)
运维·数据库·腾讯云
power 雀儿2 小时前
集群聊天服务器---MySQL数据库的建立
服务器·数据库·mysql
骑着王八撵玉兔4 小时前
【性能优化与架构调优(二)】高性能数据库设计与优化
数据库·性能优化·架构
Edingbrugh.南空4 小时前
Flink MySQL CDC 环境配置与验证
mysql·adb·flink