📜  SQL CTE(公用表表达式)(1)

📅  最后修改于: 2023-12-03 14:47:34.811000             🧑  作者: Mango

SQL CTE

SQL CTE (Common Table Expression) 是一种临时命名的结果集,它在 SQL Server 中查询中的多个地方使用。 CTE 可以用于创建递归查询,但与临时表不同,CTE 只存在于查询的执行周期中。

使用 CTE

CTE 在 WITH 关键字后定义,其后紧跟 CTE 名称和列名(如果有)。 CTE 主体与SELECT语句主体一样,其后必须跟随一个分号。

WITH <CTE名称> (<列1名称>, <列2名称>, ...) AS  
(  
  <CTE查询语句>  
)  
--下面的语句使用了 CTE(例子)  
SELECT * FROM <CTE名称>

在上面的语句中,<CTE名称> 是临时定义的表格名称。 该表格包含列(列1,列2等)和数据,这些数据是通过<CTE查询语句>获得的。 对于查询所返回的数据,现在可以使用 <CTE名称>。

CTE 示例
WITH EmployeeSales AS  
(  
    SELECT  EmployeeID, SUM(TotalDue) AS TotalSales  
    FROM    Sales.SalesOrderHeader  
    WHERE   SalesPersonID IS NOT NULL  
    GROUP BY EmployeeID  
)  
SELECT  e.EmployeeID,  
    COUNT(soh.SalesOrderID) AS TotalOrders,  
    ROUND(SUM(soh.TotalDue),2) AS TotalDue,  
    es.TotalSales  
FROM    Sales.SalesOrderHeader AS soh   
    JOIN HumanResources.Employee AS e   
        ON e.EmployeeID = soh.SalesPersonID  
    JOIN EmployeeSales AS es   
        ON es.EmployeeID = e.EmployeeID  
GROUP BY e.EmployeeID, es.TotalSales  
ORDER BY es.TotalSales DESC;

上面的示例中,CTE EmployeeSales 是定义的临时表格名称。 其主体是一个查询语句,该查询语句从 Sales.SalesOrderHeader 表中获取所有员工的销售总额。 现在,该表格可以在后续查询中用作过滤条件和数据来源。

在下面的语句中,查询显示了每个销售人员的销售情况。 它使用 EmployeeSales CTE,并连接 Employee 和 Sales.SalesOrderHeader 表。

递归查询

CTE 还可以用于创建递归查询。 在递归查询中,SELECT 语句通过使用插入到 CTE 中的数据以递归方式引用自身。

例如,在下面的代码片段中,CTE 是为 AdventureWorks 数据库中的所有组织单元创建的。此 CTE 支持递归查询,因为它引用自身(在这种情况下,通过使用父组织单元 ID):

WITH OrganizationUnits (OrganizationUnitID, ParentOrganizationUnitID, Name)   
AS   
(   
    SELECT OrganizationUnitID, ParentOrganizationUnitID, Name   
    FROM HumanResources.Department   
    WHERE ParentOrganizationUnitID IS NULL    
    UNION ALL   
    SELECT d.OrganizationUnitID, d.ParentOrganizationUnitID, d.Name   
    FROM HumanResources.Department d   
         JOIN OrganizationUnits ou   
            ON d.ParentOrganizationUnitID = ou.OrganizationUnitID   
)   
SELECT OrganizationUnitID, Name, ParentOrganizationUnitID   
FROM OrganizationUnits   
ORDER BY OrganizationUnitID   

该查询的属性如下:

  • 组织单元 CTE 包括 OrganizationUnitID、 Name 和 ParentOrganizationUnitID 列。
  • 初始查询检索 CTE 中根部门的所有行。
  • 联合 ALL 操作联接初始行和后续查询中的行。
  • 在联接查询中,从 已经检索的行中 记录了父组织单元 ID。
  • 如果查询没有找到匹配的父组织单元,那么递归查询终止,并生成最终结果。
  • UNION ALL 在匹配父组织单元时将其递归到下一行中。
总结

CTE 是 SQL 的一种功能强大的工具,它可以在查询中重用临时表格数据。 使用 CTE,可以减少代码和其他查询中的代码冗余,从而使数据查询相关的任务更加轻松。