1 CTE语法WITH关键字
通用表表达式(Common Table Express, CTE),将派生表定义在查询的最前面。要使用CTE开始创建一个查询,可以使用WITH关键字。
CTE语法:
WITH[(column_name [,...n])] AS ( CTE_query_definition) [, ]
首先为CTE提供一个名称,该名称类似于用于派生表的别名。然后可以提供CTE将返回的列名列表;如果CTE指定了它的所有返回列,则这是可选操作。最后,在圆括号中添加CTE查询的定义,最后添加使用CTE的主查询。
WITH关键字之前的语句必须使用分号(;)结束。
示例
WITH cteAS( SELECT * FROM [dbo].[Product])SELECT [ProductID],[ProductCode],[ProductName],[UnitPrice] FROM cte
连接查询示例
WITH ProductCTE([CategoryID], [ProductsCount])AS( SELECT [CategoryID],COUNT(1) FROM [dbo].[Product] GROUP BY [CategoryID])SELECT c.[CategoryID],c.[CategoryName], cte.[ProductsCount]FROM [dbo].[Category] cINNER JOIN ProductCTE cte ON c.[CategoryID] = cte.[CategoryID]ORDER BY cte.[ProductsCount]
2 使用多个CTE
使用WITH开始语句可以定义多个CTE,不需要重复使用WITH关键字,每一个CTE可以使用在该语句中已经定义的任意CTE(作为其定义的一部分)。
WITH CategoryCTEAS( SELECT * FROM [dbo].[Category]),ProductCTEAS( SELECT p.*,cte.[CategoryName] FROM [dbo].[Product] p INNER JOIN CategoryCTE cte ON p.[CategoryID] = cte.[CategoryID])SELECT * FROM ProductCTE
3 递归CTE
递归公用表表达式是在CTE内的语句中调用其自身的CTE。
示例
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])AS( -- 查询语句 SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 递归语句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID])SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cte
限制递归层次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])AS( -- 查询语句 SELECT [CategoryID],[CategoryName],[ParentID],1 AS [Level] FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 递归语句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], cte.[Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID])SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cteOPTION(MAXRECURSION 2)
Where过滤递归结果数据层次
WITH cte([CategoryID],[CategoryName],[ParentID],[Level])AS( -- 查询语句 SELECT [CategoryID],[CategoryName],[ParentID],1 FROM [dbo].[Category] WHERE [ParentID] IS NULL UNION ALL -- 递归语句 SELECT c.[CategoryID],c.[CategoryName],c.[ParentID], [Level] + 1 FROM [dbo].[Category] c INNER JOIN cte ON c.[CategoryID] = cte.[ParentID])SELECT [CategoryID],[CategoryName],[ParentID],[Level] FROM cteWHERE cte.[Level] <= 3