with as 和with recursive 用法


玛卡,巴卡,阿卡,哇卡,米卡,玛卡,呣!
玛卡,巴卡,阿巴,雅卡,伊卡,阿卡,噢!
哈姆,达姆,阿卡嗙,咿呀呦~ 玛卡,巴卡,阿卡,哇卡,米卡,玛卡,呣!

with as 用法

在mysql中,“with as”也叫子查询,用于定义一个sql片段,且该片段会被整个sql语句反复使用很多次,这个sql片段就相当于是一个公用临时表,语法为“with tmp as (查询语句)”。

WITH AS短语,也叫做子查询部分(subquery factoring),可以定义一个SQL片断,该SQL片断会被整个SQL语句用到。可以使SQL语句的可读性更高,也可以在UNION ALL的不同部分,作为提供数据的部分。

常用语法

  • 针对一个别名
WITH tem AS ( SELECT * FROM dept)
  • 针对多个别名
WITH tem AS ( SELECT * FROM dept),
	tem1 AS ( SELECT * FROM dept1),
	tem2 AS ( SELECT * FROM dept2),
	...
  • 构建tem临时表
WITH tem AS ( SELECT * FROM dept) SELECT * FROM tem
  • 构建tem_code,tem_name临时表,并指定所需字段
WITH tem_code ( dept_code ) AS ( SELECT dept_code FROM dept ),
	tem_money ( dept_code, money ) AS ( SELECT dept_code, money FROM dept_expense ) 
SELECT
	* 
FROM
	tem_code
	INNER JOIN tem_money ON tem_code.dept_code = tem_money.dept_code
  • 构建tem临时表,通过自己编写方式构建
WITH tem ( dept_code, dept_name, date ) AS (
	VALUES
		ROW ( "1614470462714445825", "营销部", "2022-01" ),
		ROW ( "1614470959278095767", "销售部", "2022-01" ),
		ROW ( "1614471266527641602", "设计部", "2022-01" ),
		ROW ( "1614471057957486593", "宣传部", "2022-01" ) 
	) SELECT
	*
FROM
	tem

其实就是把一大堆重复用到的sql语句放在with as里面,取一个别名,后面的查询就可以用它

with recursive递归的使用

语法

WITH recursive 表名 AS ( 
	初始语句(非递归部分) 
	UNION ALL 
	递归部分语句
)
[ SELECT| INSERT | UPDATE | DELETE]

with as 业务需求场景

查询统计各部门2022年01月总支出金额,如果该部门下为有支出金额显示0。

设有四个部门,在2022年01月只有两个部门有支出金额记录。

数据库表

以下表做演示使用

部门表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for dept
-- ----------------------------
DROP TABLE IF EXISTS `dept`;
CREATE TABLE `dept`  (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `dept_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '部门编码',
  `dept_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '部门名称',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of dept
-- ----------------------------
INSERT INTO `dept` VALUES (1, '1614470462714445825', '营销部');
INSERT INTO `dept` VALUES (3, '1614470959278095767', '销售部');
INSERT INTO `dept` VALUES (4, '1614471266527641602', '设计部');
INSERT INTO `dept` VALUES (5, '1614471057957486593', '宣传部');

部门消费表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for dept_expense
-- ----------------------------
DROP TABLE IF EXISTS `dept_expense`;
CREATE TABLE `dept_expense`  (
  `id` bigint NOT NULL AUTO_INCREMENT,
  `dept_code` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `money` decimal(20, 8) UNSIGNED ZEROFILL NOT NULL,
  `create_time` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of dept_expense
-- ----------------------------
INSERT INTO `dept_expense` VALUES (1, '1614470959278095767', 3000.00000000, '2022-01-01 11:04:28');
INSERT INTO `dept_expense` VALUES (2, '1614470462714445825',9000.00000000, '2022-01-02 11:05:24');

数据查询

查询各部门总支出金额

查询各部门总支出金额,sql如下:

SELECT
	dt.dept_code,
	dt.dept_name,
	SUM( dte.money ) AS money 
FROM
	dept AS dt
	LEFT JOIN dept_expense AS dte ON dt.dept_code = dte.dept_code 
	WHERE DATE_FORMAT(dte.create_time,"%Y-%m") = DATE_FORMAT("2022-01-01","%Y-%m")
GROUP BY
	dt.dept_code,
	dt.dept_name

在这里插入图片描述

这样统计只统计了有支出金额数据的部门

结合临时表查询各部门总支出金额

查询各部门总支出金额,sql如下:

WITH tem ( dept_code, dept_name, date ) AS ( SELECT dept_code, dept_name, "2022-01" AS date FROM dept ) SELECT
	tem.dept_code,
	tem.dept_name,
	tem.date,
IF
	( ISNULL( mm.money ), 0, mm.money ) AS money 
FROM
	tem
	LEFT JOIN (
	SELECT
		dt.dept_code,
		dt.dept_name,
		SUM( dte.money ) AS money 
	FROM
		dept AS dt
		LEFT JOIN dept_expense AS dte ON dt.dept_code = dte.dept_code 
	WHERE
		DATE_FORMAT( dte.create_time, "%Y-%m" ) = DATE_FORMAT( "2022-01-01", "%Y-%m" ) 
	GROUP BY
		dt.dept_code,
		dt.dept_name 
	) AS mm ON mm.dept_code = tem.dept_code

在这里插入图片描述

构建临时表tem,在与mm表进行连表查询即可。结合mybatis动态sql使用更佳

with recursive 业务需求场景

仓库分布在各个省市区内,仓库表为一个自关联表
需求查询出京海市下所有的仓库

数据库表

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for store
-- ----------------------------
DROP TABLE IF EXISTS `store`;
CREATE TABLE `store`  (
  `ID` bigint NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `PARENT_ID` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '上级仓库编码',
  `STORE_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '仓库名称',
  PRIMARY KEY (`ID`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 36 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '仓库管理' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of store
-- ----------------------------
INSERT INTO `store` VALUES (1, NULL, '京海市仓库');
INSERT INTO `store` VALUES (2, '1', '京海市-A仓库');
INSERT INTO `store` VALUES (3, '1', '京海市-B仓库');
INSERT INTO `store` VALUES (4, '3', '京海市-B-xxx仓库');
INSERT INTO `store` VALUES (5, NULL, '汉东市仓库');

数据查询

查询出京海市下所有的仓库

WITH recursive temp AS(
    SELECT * FROM store WHERE STORE_NAME = '京海市仓库'
    UNION ALL
    SELECT u.* FROM store u,temp t WHERE u.PARENT_ID=t.ID
)
SELECT * FROM temp;

在这里插入图片描述

如有问题请指出

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WITH RECURSIVE cte AS是一种在SQL语句中使用递归的方式。它可以用来创建一个临时的递归表格,并在表格中进行递归操作。\[1\] 在这个语法中,cte是递归表格的名称,可以在后续的SQL语句中引用。递归表格的定义包括两部分:初始值和递归内容。初始值是指递归表格的初始行,而递归内容是指在每次递归时要添加到表格中的行。递归内容可以引用递归表格本身,以实现递归操作。 在递归表格的定义中,可以使用UNION ALL将初始值和递归内容组合在一起。递归内容中的WHERE子句用于指定递归的终止条件,以防止无限递归。 使用WITH RECURSIVE cte可以实现各种递归操作,例如计算累加和、查询层级关系等。\[3\] \[2\] 希望这个解释对您有帮助。 #### 引用[.reference_title] - *1* [SQL:With recursive 递归用法](https://blog.csdn.net/WHYbeHERE/article/details/125440856)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [WITH RECURSIVE 递归 与with as 子查询部分](https://blog.csdn.net/weixin_42871919/article/details/129436417)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值