备注:测试数据库版本为MySQL 8.0

这个blog我们来聊聊MySQL的with语句
对于逻辑复杂的sql,with可以大大减少临时表的数量,提升代码的可读性、可维护性

MySQL 8.0终于开始支持with语句了,对于复杂查询,可以不用写那么多的临时表了。

如需要scott用户下建表及录入数据语句,可参考:
scott建表及录入数据sql脚本

语句结构:

with subquery_name1 as (subquery_body1),subquery_name2 as (subquery_body2)
...
select * from subquery_name1 a, subquery_name2 b
where a.col = b.col
...

优势
– 代码模块化
– 代码可读性增强
– 相同查询唯一化

一.提升代码的可读性和可维护性

需求:求每个部门的平均工资,以及剔除薪资低于1000的实习人员之后的平均工资

-- 求每个部门的平均工资,以及剔除薪资低于1000的实习人员之后的平均工资
-- 主查询的from后面跟了2个临时表,程序可读性不佳
select d.deptno, tmp1.avg_sal avg_sal1, tmp2.avg_sal avg_sal2from dept dleft join (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_salfrom emp e1group by e1.deptno) tmp1on d.deptno = tmp1.deptnoleft join (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_salfrom emp e1where e1.sal > 1000group by e1.deptno) tmp2on d.deptno = tmp2.deptno;-- 求每个部门的平均工资,以及剔除薪资低于1000的实习人员之后的平均工资
-- 2个临时表的定时语句通过with封装成子查询了,程序可读性增强
with tmp1 as(select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_salfrom emp e1group by e1.deptno),
tmp2 as(select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_salfrom emp e1where e1.sal > 1000group by e1.deptno)
select d.deptno, tmp1.avg_sal avg_sal1, tmp2.avg_sal avg_sal2from dept dleft join tmp1on d.deptno = tmp1.deptnoleft join tmp2on d.deptno = tmp2.deptno;
mysql> -- 求每个部门的平均工资,以及剔除薪资低于1000的实习人员之后的平均工资
mysql> -- 主查询的from后面跟了2个临时表,程序可读性不佳
mysql> select d.deptno, tmp1.avg_sal avg_sal1, tmp2.avg_sal avg_sal2->   from dept d->   left join (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_sal->                from emp e1->               group by e1.deptno) tmp1->     on d.deptno = tmp1.deptno->   left join (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_sal->                from emp e1->               where e1.sal > 1000->               group by e1.deptno) tmp2->     on d.deptno = tmp2.deptno;
+--------+----------+----------+
| deptno | avg_sal1 | avg_sal2 |
+--------+----------+----------+
|     10 |  2916.67 |  2916.67 |
|     20 |  2175.00 |  2518.75 |
|     30 |  1566.67 |  1690.00 |
|     40 |     NULL |     NULL |
+--------+----------+----------+
4 rows in set (0.00 sec)mysql>
mysql>
mysql> -- 求每个部门的平均工资,以及剔除薪资低于1000的实习人员之后的平均工资
mysql> -- 2个临时表的定时语句通过with封装成子查询了,程序可读性增强
mysql> with tmp1 as->  (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_sal->     from emp e1->    group by e1.deptno),-> tmp2 as->  (select e1.deptno, round(avg(ifnull(e1.sal, 0)), 2) avg_sal->     from emp e1->    where e1.sal > 1000->    group by e1.deptno)-> select d.deptno, tmp1.avg_sal avg_sal1, tmp2.avg_sal avg_sal2->   from dept d->   left join tmp1->     on d.deptno = tmp1.deptno->   left join tmp2->     on d.deptno = tmp2.deptno;
+--------+----------+----------+
| deptno | avg_sal1 | avg_sal2 |
+--------+----------+----------+
|     10 |  2916.67 |  2916.67 |
|     20 |  2175.00 |  2518.75 |
|     30 |  1566.67 |  1690.00 |
|     40 |     NULL |     NULL |
+--------+----------+----------+
4 rows in set (0.00 sec)mysql>

二.with递归

用with递归构造数列

-- 用with递归构造1-10的数据
with RECURSIVE c(n) as(select 1   union all select n + 1 from c where n < 10)
select n from c;
-- 用with递归构造1-10的数据
mysql> with RECURSIVE c(n) as->  (select 1   union all select n + 1 from c where n < 10)-> select n from c;
+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
|    8 |
|    9 |
|   10 |
+------+
10 rows in set (0.00 sec)

用with递归构造级联关系

with RECURSIVE emp2(ename,empno,mgr,lvl)as(select ename, empno, mgr, 1 lvl from emp where mgr is nullunion allselect emp.ename, emp.empno, emp.mgr, e2.lvl+1from emp, emp2 e2where emp.mgr = e2.empno)
select lvl,concat(repeat('**',lvl),ename) nmfrom emp2order by lvl,ename
;
mysql> with RECURSIVE emp2(ename,empno,mgr,lvl)->   as->    (select ename, empno, mgr, 1 lvl from emp where mgr is null->     union all->     select emp.ename, emp.empno, emp.mgr, e2.lvl+1->       from emp, emp2 e2->      where emp.mgr = e2.empno->    )-> select lvl,->       concat(repeat('**',lvl),ename) nm->   from emp2->  order by lvl,ename-> ;
+------+---------------+
| lvl  | nm            |
+------+---------------+
|    1 | **KING        |
|    2 | ****BLAKE     |
|    2 | ****CLARK     |
|    2 | ****JONES     |
|    3 | ******ALLEN   |
|    3 | ******FORD    |
|    3 | ******JAMES   |
|    3 | ******MARTIN  |
|    3 | ******MILLER  |
|    3 | ******SCOTT   |
|    3 | ******TURNER  |
|    3 | ******WARD    |
|    4 | ********ADAMS |
|    4 | ********SMITH |
+------+---------------+
14 rows in set (0.00 sec)

MySQL with语句小结相关推荐

  1. MySQL基础语句小结

    一.基础 1.说明:创建数据库 CREATE DATABASE database-name 2.说明:删除数据库 drop database dbname 3.说明:备份sql server --- ...

  2. MySQL UPDATE 语句一个“经典”的坑

    转载自  MySQL UPDATE 语句一个"经典"的坑 来源:ju.outofmemory.cn/entry/336774 有问题的SQL语句 why? 倒回去再重试验一把 最近 ...

  3. MySQL数据库——语句

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.MySQL数据库语句 (一).按关键字排序 1.可进行多字段的排序 (二).单字段排序 1.按分数排序,默认不指定 ...

  4. MySQL中定义fk语句_MySQL基础篇/第3篇:MySQL基本操作语句.md · qwqoo/MySQL-Review - Gitee.com...

    ### 第3篇:MySQL基本操作语句 - MySQL基础操作 #### 排序检索数据 - 之前的数据没有进行排序,其是按照默认在数据表中的数据返回的 - SELECT语句的ORDER BY 子句进行 ...

  5. mysql等价语句是_Mysql基本语句(个人笔记)

    mysql基本操作语句 1 数据库的基本操作 create database doem default charset utf8; -- 创建数据库 字符编码 utf8 show database; ...

  6. mysql for 语句执行顺序_MySQL查询语句的执行流程

    MySQL可以抽象分为 Server 和存储引擎. Server 包括 连接器,分析器,优化器,执行器等. 存储引擎负责数据的存储和具体查询.存储引擎是可插拔式的,支持 InnoDB,MyISAM 等 ...

  7. MySQL语法语句大全

    MySQL语法语句大全 一.SQL速成   ; B/ X* Q; t/ W) v" ]结构查询语言(SQL)是用于查询关系数据库的标准语言,它包括若干关键字和一致的语法,便于数据库元件(如表 ...

  8. python拼接sql语句_【Python】拼接MySQL常用语句

    import pymysql class MK_sql (): """ 构建mySQL常见语句:增删改查排序 """ def __init_ ...

  9. 导出mysql sql语句吗_mysql sql语句导入与导出

    mysql sql语句导入与导出 导入: mysql -u root -p 数据库名 如: C:/mysql/bin>mysql -u root -p house < c:/1-1.txt ...

最新文章

  1. 3638MySQL数据库应用答案_Mysql数据库多实例配置
  2. 分布式锁的三种实现方式_分布式锁的几种实现方式~
  3. 全国计算机等级考试题库二级C操作题100套(第06套)
  4. Linux学习笔记(二)
  5. 三星电视机的极光TV显示服务器异常,三星液晶电视机故障有哪些 三星液晶电视机故障解决方法【图文】...
  6. r730服务器内置SD卡位置,已解决: RE: 关于r730xd做存储服务器的疑问 - Dell Community...
  7. 3.5 将 Batch Norm 拟合进神经网络
  8. 增强for循环:本质是迭代器
  9. [LeetCode] Surrounded Regions, Solution
  10. Android wakelock机制
  11. 右手螺旋判断磁感应强度方向_弹簧左旋or右旋在功能和应用上有什么区别,如何判断左旋还是右旋...
  12. 获取.jar文件运行时所处的路径
  13. js基础-18-js中创建对象的几种方式
  14. ubuntu 右键选单没有创建文档
  15. ECG信号三大主要噪声-基线漂移,工频干扰,肌电干扰
  16. 今年职高计算机数学高考试题,2018-2019高职高考数学试题
  17. postgresql设置自动更新时间方法
  18. 公链性能差,研发难度高,区块链游戏的痛点如何解决?
  19. 基于R语言的DICE(Dynamic Integrated Model of Climate and Economy)模型
  20. wyse瘦客户机装系统_Wyse 瘦客户机流程更新

热门文章

  1. 这种蔬菜水果店管理技巧,简直就是王炸操作!
  2. nandflash和norflash的区别
  3. 最全C#自学资源汇总
  4. android usb 开发:如何跳过usb权限询问,解决绕过android下apk使用usb设备权限查询相应问题,自动获取usb权限...
  5. matlab彩色碎片拼接与复原_碎纸片的拼接复原算法及MATLAB实现.doc
  6. 软件工程课程设计“作业管理系统”的总结和期望
  7. React Native: Unexpected token ‘:‘. Expected a ‘)‘ or a ‘,‘ after a parameter declaration
  8. python第三方库-urllib(简单好用)
  9. IDEA中Maven导包问题Could not find artifact xxx或Could not resolve 可能是 设置Setting文件无效
  10. 优利德UT61E+ 说明书电子版 - 技术参数节选