MsSql “with”用法

本文介绍了使用SQL创建产品表和数据属性表,并通过查询获取特定属性值的过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CREATE TABLE #PRODUCT(id INT,NAME1 NVARCHAR(10))
CREATE TABLE #DATA_ATTRIBUTE_ABOUT_PRODUCT(id INT,type1 INT)
CREATE TABLE #DATA_ATTRIBUTE(id INT,NAME1 NVARCHAR(10),name2 NVARCHAR(10))
INSERT INTO #PRODUCT VALUES (1,'AAA')
INSERT INTO #PRODUCT VALUES (2,'BBB')
INSERT INTO #DATA_ATTRIBUTE_ABOUT_PRODUCT VALUES (1,1)
INSERT INTO #DATA_ATTRIBUTE_ABOUT_PRODUCT VALUES (1,2)
INSERT INTO #DATA_ATTRIBUTE_ABOUT_PRODUCT VALUES (1,3)
INSERT INTO #DATA_ATTRIBUTE_ABOUT_PRODUCT VALUES (2,2)
INSERT INTO #DATA_ATTRIBUTE_ABOUT_PRODUCT VALUES (2,3)

INSERT INTO #DATA_ATTRIBUTE VALUES (1,'COUNT','500')
INSERT INTO #DATA_ATTRIBUTE VALUES (2,'COLOR','RED')
INSERT INTO #DATA_ATTRIBUTE VALUES (3,'SIZE','100*200');

--SELECT a.ID,a.Name,MAX(CASE WHEN a.Name1='COUNT' then a.Name2 ELSE '' end) AS [COUNT]
--,MAX(CASE WHEN a.Name1='COLOR' then a.Name2 ELSE '' end) AS [COLOR]
--,MAX(CASE WHEN a.Name1='SIZE' then a.Name2 ELSE '' end) AS [SIZE]
--FROM(
--SELECT a.id,a.Name1 AS Name,c.Name1,c.name2
--FROM #PRODUCT a
--LEFT JOIN #DATA_ATTRIBUTE_ABOUT_PRODUCT b ON a.id = b.id
--LEFT JOIN #DATA_ATTRIBUTE c ON b.type1=c.id
--) a
--GROUP BY a.id,a.NAME;

WITH TEMPTable AS 
(
	SELECT a.id,a.Name1 AS Name,c.Name1,c.name2
	FROM #PRODUCT a
	LEFT JOIN #DATA_ATTRIBUTE_ABOUT_PRODUCT b ON a.id = b.id
	LEFT JOIN #DATA_ATTRIBUTE c ON b.type1=c.id
)
SELECT a.ID,a.Name,MAX(CASE WHEN a.Name1='COUNT' then a.Name2 ELSE '' end) AS [COUNT]
,MAX(CASE WHEN a.Name1='COLOR' then a.Name2 ELSE '' end) AS [COLOR]
,MAX(CASE WHEN a.Name1='SIZE' then a.Name2 ELSE '' end) AS [SIZE]
FROM TEMPTable a
GROUP BY a.id,a.NAME


DROP TABLE #PRODUCT
DROP TABLE #DATA_ATTRIBUTE_ABOUT_PRODUCT
DROP TABLE #DATA_ATTRIBUTE

转载于:https://www.cnblogs.com/kinpauln/archive/2011/05/24/2055755.html

<think>嗯,用户想了解MySQL中WITH用法。首先我得回忆一下,WITH关键字在MySQL里是用于公用表表达式,也就是CTE(Common Table Expression)。记得CTE主要在查询中创建临时结果集,可以嵌套或者递归使用。 首先应该解释什么是WITH语句,也就是CTE的基本概念。然后分点说明它的两种类型:非递归和递归。可能需要举例说明,这样用户更容易理解。 用户可能想知道具体怎么用,所以得给出语法结构。比如非递归CTE的基本写法,还有递归CTE的写法。要注意MySQL中递归CTE有一些限制,比如需要使用UNION ALL,而且不能有子查询之类的,这些也需要提到。 然后,应用场景部分要分清楚非递归和递归各自适合的情况。比如非递归用于简化复杂查询,递归处理层次结构数据,比如树形结构或组织结构。 接下来,注意事项很重要。特别是递归CTE的循环问题,比如MAX_STATEMENT_TIME这样的系统变量控制执行时间,避免无限循环。同时,版本要求,MySQL8.0以上才支持CTE,这点必须指出,避免用户版本不兼容。 还要考虑用户可能遇到的常见问题,比如语法错误,比如忘记写AS或者列名不匹配,这时候例子中的正确写法能帮助他们避免错误。 再检查一下是否需要对比子查询或者临时表,说明CTE的优势,比如可读性更好,更容易维护。可能用户之前用子查询比较麻烦,CTE可以简化代码。 最后,确保例子中的SQL语法正确,尤其是使用中文注释的时候,不要出现格式错误。比如WITH后面跟着CTE名称,然后AS,接着括号内的查询。递归的例子要正确展示如何逐步生成数据,比如生成数字序列或者树形结构。 总之,结构要清晰,先介绍概念,再分类型讲解,给出语法和示例,然后应用场景和注意事项。这样用户能逐步理解WITH用法,并且知道如何在实际中使用它解决问题。</think>MySQL 中的 `WITH` 子句(公用表表达式,Common Table Expression,CTE)用于创建临时命名的结果集,可以在查询中多次引用。以下是逐步说明: --- ### 一、基本语法 ```sql WITH cte_name (column1, column2, ...) AS ( -- 子查询定义CTE SELECT ... ) SELECT * FROM cte_name; -- 主查询引用CTE ``` --- ### 二、两种类型 1. **非递归CTE** - **用途**:简化复杂查询,替代子查询或临时表 - **示例**: ```sql WITH sales_summary AS ( SELECT product_id, SUM(quantity) AS total_quantity FROM orders GROUP BY product_id ) SELECT p.product_name, s.total_quantity FROM products p JOIN sales_summary s ON p.id = s.product_id; ``` 2. **递归CTE** - **用途**:处理层次结构数据(如树形结构、组织结构) - **语法**: ```sql WITH RECURSIVE cte_name AS ( -- 初始查询(基例) SELECT ... UNION ALL -- 递归查询(引用自身) SELECT ... FROM cte_name ... ) SELECT * FROM cte_name; ``` - **示例**(生成数字序列): ```sql WITH RECURSIVE numbers AS ( SELECT 1 AS n UNION ALL SELECT n + 1 FROM numbers WHERE n < 10 ) SELECT * FROM numbers; -- 输出1到10的数字 ``` --- ### 三、典型应用场景 1. **非递归CTE** - 拆分复杂查询为多步骤 - 重复使用同一子查询结果 - 提高代码可读性 2. **递归CTE** - 遍历树形结构(如部门层级、评论嵌套) - 生成连续日期或数字序列 - 路径查找(如社交网络关系链) --- ### 四、注意事项 1. **递归CTE限制** - 必须使用 `UNION ALL`(不允许 `UNION DISTINCT`) - 递归部分不能包含: - 聚合函数(如 `SUM`) - 窗口函数(如 `ROW_NUMBER`) - 子查询 - 默认递归深度限制(可通过 `cte_max_recursion_depth` 调整,默认1000) 2. **性能优化** - 避免递归CTE无限循环(如未设置终止条件) - 对大数据量递归查询需谨慎 --- ### 五、示例:查询部门层级 ```sql WITH RECURSIVE dept_tree AS ( SELECT id, name, parent_id, 1 AS level FROM departments WHERE parent_id IS NULL -- 根部门 UNION ALL SELECT d.id, d.name, d.parent_id, dt.level + 1 FROM departments d JOIN dept_tree dt ON d.parent_id = dt.id ) SELECT * FROM dept_tree; ``` --- ### 六、版本要求 - **MySQL 8.0+** 才支持完整的CTE功能 - 低版本需通过子查询或临时表替代 通过合理使用 `WITH` 子句,可以显著提升复杂查询的可读性和维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值