• MySQL之DQL语句


    查询语句

    • DQL:数据库查询语句
    • DQL 字句执行顺序
      • from → where → group by → having → select → order by
    条件运算符
    类型运算符作用
    between...and...在某一区间(闭区间)
    in(set)在 in 列表中的任一值(非区间);例如:in(100,200)
    like模糊查询,包含
    not like模糊查询,不包含
    is null为空
    is not null不为空
    not不成立;例如:where not (salary = 5000)
    比较> 、< 、<= 、>= 、= 、!=(<>)大于、小于、小于等于、大于等于、等于、不等于
    逻辑and多条件同时成立
    or多条件任一成立
    • MyBatisMapper 文件中 使用运算符会将 < 标记为尖括号
      • 使用 使编译器忽略 [] 里内容
        • 或使用 $lt;表示 <
        • 使用 >表示 >,在 MyBaits> 可直接使用
      • 替换符号可直接和运算符连接使用
        • <= 表示 <=
    条件查询
    • 查询指定字段(column)的数据

      • 多个字段 , 隔开
      • * 代表查询所有字段
        • 实际开发不建议使用,全字段查询效率较低
      • from:要查询的表
      • where:筛选字段的条件
    • 字段可以参与数学运算

      • 计算的字段都为都为数值类型
    • distinct:去除查询出的完全一样的记录

      • 只能在所有字段最前面

      • 不能用在中间指定某一个字段

    • as:指定查询的字段在查询结果中的暂时别名

      • 可省略
    -- 从 student 表中查询每个学生的总分,显示姓名和总成绩
    select [distinct] * /* 或 column1, column2... */ from `table_name` where 限定条件;
    
    -- 语文、数学、英语成绩相加查询显示为一列,取别名 total
    select `name`, (Chinese + Math + English) as total from student
    
    • 1
    • 2
    • 3
    • 4
    • 5
    模糊查询
    • like:模糊查询
      • %:表示任意多个字符
      • _:(下划线)表示任意单个字符
    • not like
    like '%A%';				-- 含有A的记录
    like '%A';				-- 以 A 结尾
    like 'A%';				-- 以 A 开头
    like '__A%';			-- 第三个字母为 A,两个下划线
    like '%\_%';			-- 转义字符使用,含有 _ 的记录
    not like '%A%';			-- 不包含 A 的记录
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    排序查询
    • order by 指定排序的列,排序的的列可以是表中的列名,也可以是指定的别名
      • asc 升序(默认)
      • desc 降序
      • 可根据字段顺序排列
        • order by 2:根据第二个字段排序
        • 字段顺序发生改变后查询结果错误
    • order by 子句应位于 select 语句的结尾
      • 指定按多列排序 , 分隔
      • 前一轮排序相等才进入下一轮排序
    • 执行顺序
      • from → where → group by → having → select → order by
    select column1 as name from `table_name` order by `column1` /*或 name */ asc /*或 desc*/
    -- 查找姓李的数学成绩降序,语文成绩升序排列(显示姓名、数学成绩、语文成绩)
    select name,math,chinese from student where name like '李%' order by math desc, chinese asc
    
    • 1
    • 2
    • 3
    分组函数
    • 又叫多行处理函数
      • 处理多行数据,最终输出一行
    • 自动忽略 null
      • 统计结果时 null 不参与
    • 不可直接使用在 where 语句中
      • 通常 分组函数 和 group by 联合使用
        • 且 分组函数 在 group by 之后执行
        • group bywhere 之后执行
      • 没有显式声明 group by 时整表作为一组执行
    • 可组合使用
    count()
    • 统计函数
      • count(*):统计满足条件的总记录条数
        • 与某字段无关
        • 或使用 count(常量) 效果一样
      • count(字段):统计此字段满足条件且不为 null 的记录数
    select count(*)/* count(列名) */ from `table_name` where 限定条件
    -- 统计姓名不为空的数学成绩大于80的总人数
    select count(name) from student where math > 80
    
    • 1
    • 2
    • 3
    sum()
    • sum() 返回该列满足 where 条件的行的和
      • 适用于数值列,仅对数值起作用
      • 对多列分别求和时 , 不能少
    select sum(列名), sum(列名) from `table_name` where 限定条件
    -- 求出所有人的数学总成绩之和 及 英语和语文总成绩之和
    select sum(Math), sum(English + Chinese) from student
    
    • 1
    • 2
    • 3
    avg()
    • 返回满足条件的字段的平均值
    select avg(列名), avg(列名) from `table_name` where 限定条件
    -- 求一个班数学平均分和总分平均分
    select avg(Math),avg(Math + English + Chinese) from student
    
    • 1
    • 2
    • 3
    max()、min()
    • 返回满足条件的所有记录中的最值
    select max(列名) /* min(列名) */ from `table_name` where 限定条件
    -- 求班级最高分和最低分指定为max、min
    select max(Math + English + Chinese) as 'max',min(Math + English + Chinese) as 'min' from student
    
    • 1
    • 2
    • 3
    分组统计
    • group by:根据某字段分组
      • 对查询结果分组统计
      • 多字段联合分组 , 分隔
        • 先按照前面字段分组
      • group by 分组时 select 只能查询分组相关字段和 分组函数
        • 即 select 后字段必须使用分组函数或出现在 group by 后
        • Oracle 中语法严格会直接报错
        • MySQL 中语法比较松散可以执行
          • 但查询其他字段毫无意义,会随机显示该字段记录
    • having:筛选记录
      • 限制分组显示结果
      • 必须跟在 group by 后面
    • 执行顺序
      • from → group by → select
      • 通常 分组函数 和 group by 联合使用
        • 且 分组函数 在 group by 之后执行
      • 未显式声明 group by 时整张表作为一组执行
    -- group by 分组;分组后使用 having 字句进行过滤
    select column1 from `table_name` group by `column` having 限定条件
    
    -- 显示每个部门平均工资大于 2000 的每个岗位的薪资平均值和最低值
    -- 先根据部门分组,再根据岗位分组;使用别名筛选,值只计算一次,效率高一些
    select avg(salary) as avg_sal, min(salary), deptno, job 			-- salary 字段未分组,但使用了分组函数
    from `table_name` 
    group by deptno, job 
    having avg_sal > 2000
    
    -- 该分组查询可以执行,但结果无意义
    /*
    以 job 分组,但查询了 enamel、sal;这两个字段会随机显示一条记录;结果无实际意义
    在 Oracle 更严格的语法规范中无法执行通过
    */
    select ename, avg(sal), sal, job 
    from emp 
    group by job
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    多表查询
    连接查询

    多表查询需要使用连接进行查询

    分类
    • 按语法出现年代
      • SQL 92
        • 一些较老的 DBA 可能还在使用
        • DBA:数据库管理员
          • Database Administrator
        • 语法
          • 多表使用 , 隔开
          • 连接条件写在 where 字句
      • SQL 99
        • 相对较新的语法
          • ...join... on...
        • 多表使用 join 连接
          • 连接条件写在 on 字句
        • 表连接条件与 where 条件分离
          • 结构更清晰
    • 按表的连接方式
      • 内连接
        • 等值连接
        • 非等值连接
        • 自连接
      • 外连接
        • 左外连接
        • 右外连接
      • 全连接:很少使用
    内、外连接
    • 内连接
      • 多表使用内连接,凡是能匹配的记录全部查询出来
      • 两张表没有主副之分
    • 外连接
      • 多表外连接有主副表之分
      • 主要查询主表数据,同时查询副表数据
      • 即 主表数据全部显示,副表只显示匹配数据
        • 副表不匹配的数据显示 null
    笛卡尔积

    两张表同时查询

    1. 默认一张表中每一行和另一张表每一行组合并返回结果
      • 即两张表进行排列组合
      • 总记录数 = 第一张表记录数 * 第二张表记录数
    2. 默认返回的结果称为多表笛卡尔集
      • 多表查询不含过滤条件就会出现笛卡尔积现象
      • 加条件过滤以避免笛卡尔积现象,但查询次数不会减少
        • 次数 = 表记录数 * 另一张表记录数
        • 只显示有效记录

    处理过滤条件限定查询结果

    • 多表查询时过滤条件不能少于表数量 - 1
      • 至少有任两张表有相关字段约束
    • select 杳询的多表公有的字段必须标明所属表
      • 例如:emp.deptno
    • 两张表之间要有相关联的列作为约束进行多表查询
      • 相同字段各自标明所属表,并以该字段为唯一列查询
        • 例如:emp.deptno = dept.deptno
      • 一张表的字段在另一张表中筛选
        • 例如:sal between losal and hisal
    内连接
    等值连接
    • 连接条件为等值关系
    -- 语法; inner 可省略
    select 字段 from A [inner] join B on 连接条件 where 限定条件
    /*
    SQL 99 语法,表连接条件 与 where 条件分离
    */
    select name, emp.deptno, dname from emp join dept		-- 从 emp、dept 两张表中查询显示name、deptno、dname
    on emp.deptno = dept.deptno								-- 对两张表中相同的字段作为连接条件进行查询
    
    /*
    SQL 92 语法,连接条件在 where 中
    */
    select name, emp.deptno,dname from emp, dept
    where emp.deptno = dept.deptno
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    非等值连接
    • 连接条件关系不是等值关系
    -- 语法相同
    select ... from A join B on ... where ...
    -- 显示员工姓名,工资,工资级别;姓名、工资在表emp,工资级别在表salgrade
    select ename, sal, grade from emp join salgrade
    on sal between losal and hisal			-- 连接条件为最低工资和最高工资之间
    
    • 1
    • 2
    • 3
    • 4
    • 5
    自连接
    • 将一张表当作两张表使用

      • 需要使用表别名查询,否则无法定义字段归属
    -- 同时显示员工名和对应的上级名
    -- 将emp表当作两张表分别取别名a、b,同时显示两张表中的ename
    select a.ename as '员工', b.ename as '上级' from emp a join emp b
    on a.mgr = b.empno				-- 连接条件一张表的上级编号等于另一张表的员工编号
    
    • 1
    • 2
    • 3
    • 4
    外连接
    • 即使筛选条件不匹配也全部显示,使用最多

      • 多表外连接有主副表之分
        • 主要查询主表数据,同时查询副表数据
        • 即主表数据全部显示,副表只显示匹配数据
          • 副表不匹配的数据显示 null
    • 主表满足条件的记录无视连接条件条件全部显示

    -- 语法;outer 可省略
    左表 left / right [outer] join 右表 on 连接条件
    
    • 1
    • 2
    左外连接

    左边表即使连接条件不匹配也全部显示

    -- 左外连接,tab1表即使不满足限定条件也显示对应记录
    select * from tab1 left join tab2 on 限定条件
    
    • 1
    • 2
    右外连接

    右边表即使连接条件不匹配也全部显示

    -- 右外连接,tab2表即使不满足限定条件也显示对应记录
    select * from tab1 right join tab2 on 限定条件
    
    • 1
    • 2
    多表查询
    • 三张及以上表
    -- A 先连接 B,连接之后 A 再连接 C 
    select ... 
    from A join B 
    	on ... 
    	join C 
    	on ... 
    	join ... 
    where...
    
    -- 查询每一个员工的部门名称、工资等级、上级领导
    select e.ename '员工', d.dname, s.grade, e1.ename '领导' 
    from emp e join dept d 
    	on e.deptno = d.deptno					-- 内连接 dept 表
    	join salgrade s 
    	on e.sal between losal and hisal		-- 内连接 salgrade 表
    	left join emp e1 
    	on e.mgr = e1.empno;					-- 左连接自身
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    子查询
    • 嵌入在其它 sql 语句中的 select 语句,也叫嵌套子查询
    • 将一次查询的结果当作数据嵌套入另一次查询中
      • 作为 where 语句条件
      • 作为临时表数据
      • 也可嵌套在 select 字句
    临时结果
    • 将子查询结果当作数据使用在 where 子句中
    • 或使用在 where 语句中
      • in() 操作符:其中一个
      • all() 操作符:满足所有
      • any() 操作符:满足任意一个
    # 嵌套子查询了:跟 SIMTH 一个部门的员工,不包括SMITH
    select ename from emp 
    where job = (
        select job from emp where ename = 'smith'
    ) and ename != 'smith'
    
    # in 操作符
    -- 查询跟10号部门有相同职位的人的姓名、职位、工资、编号,不包括10号部门
    select ename, job, sal, deptno from emp
    where job in ( 								-- 在下列的结果之中的其中一个
    	select distinct job from emp 	
        where deptno = 10 						-- 查询在10号部门的职位并去重
    ) and deptno != 10							-- 不包括 10 号部门
       	
    # all 操作符
    -- 查询所有工资大于30部门所有人工资的人姓名、工资、部门号
    select ename, sal, deptno from emp
    where sal > all(							-- 大于所有
    	select sal from emp where deptno = 30	-- 部门编号为 30 的员工的工资
    )   
    -- 或者 where sal > (select max(sal) ...)   -- 大于最大值
         
    # any 操作符
    -- 查询所有工资大于30部门其中一人工资的人姓名、工资、部门号
    select ename, sal, deptno from emp
    where sal > any(							-- 大于任意一个
    	select sal from emp where deptno = 30 	-- 30 号部门工资
    )  
    -- 或者 where sal > (select min(sal) ...)	  -- 大于最小值
    
    # 嵌套 select 查询员工名、部门名
    select ename, (select dname from dept d 
         where e.deptno = d.deptno ) 
    from emp e
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    多列匹配
    • (deptno, job) =(select deptno, job from ...
      • 等价于 deptno = Smith.deptno and job = smith.job
      • 括号中对应位置数据匹配
    -- 查询所有人中和smith的部门、职位相同的员工
    select * from emp
        where (deptno, job) = ( 
        	select deptno, job from emp  
                    where ename = 'smith'	-- 查询simth的职位
        ) and ename != 'smith'
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    临时表
    • 将子查询的结果当作临时表使用

      • 临时表中出现的列名和原表中相同的也需要表明
    -- 查询ecs表中各类商品中最高价格的商品名、商品id、价格
    select goods_id, ecs.cat_id,goods_name,shop_price
    from( 
        select cat_id, max(shop_price) as max_price					-- 先查询ecs表中各类别商品最高价格 
        from ecs	      
        group by cat_id  										    -- 根据类别分组		
        ) temp join ecs  	-- 将查询出的结果当临时表来用,取别名 temp;和 ecs 内连接查询
    on temp.cat_id = ecs.cat_id and temp.max_pricee = ecs.shop_price	-- 连接条件为 id 、价格 相等
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    合并查询
    • 合并多个 select 语句的结果

      • 集合操作符:union、union all
    • union all

      • 将两个结果集合并,使用时不会取消重复行
    • union

      • 将两个查询结果集取并集,重复纪录只显示一次
    • 可用于毫无相关的表拼接数据

      • 拼接时不同查询的字段数要相等
    select ename from emp where job = 'MANAGER'
    union all
    select ename from emp where job = 'SALESMAN';
    
    • 1
    • 2
    • 3
    分页查询
    • 分页公式
      • limit 每页记录数 * ( 页数 - 1 ), 每页记录数
    -- 语法
    select ... limit start, rows
    -- 从第 start + 1 行开始取,取rows行; start从 0 开始
    
    -- 显示部门id和平均工资
    select id, avg(salary) as avg_sal
    from employee
    where id = 20
    group by id					-- 根据 id 分组
    having avg_sal > 1000		-- 平均工资大大于 1000 
    order by avg_sal desc		-- 各部门内根据平均工资降序
    limit 0, 2 					-- 显示第一页两行记录;或 limit 2: 默认从 0 开始
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    sql执行顺序

    执行顺序

    • from → where → group by → having → select → order by → limit
  • 相关阅读:
    c++ 继承
    Java Executors类的9种创建线程池的方法及应用场景分析
    Flutter 基本概念
    Linux 学习笔记(5-6)
    用HTML、CSS技术设计的个人网页与实现制作(web前端期末大作业)
    【数仓】数据仓库高频面试题题英文版(1)
    因果系列文章(7)——干预工具(下)
    Windows下网络编程及多线程模型
    如何使用 Git 管理配置文件
    【7 Vue3 – Composition API】
  • 原文地址:https://blog.csdn.net/qq_66991094/article/details/126573762