【问题标题】:Keeping it simple and how to do multiple CTE in a query保持简单以及如何在查询中执行多个 CTE
【发布时间】:2010-01-26 16:22:40
【问题描述】:

我有这个简单的 T-SQL 查询,它从一个表中发出一堆列,还连接来自其他相关表的信息。

我的数据模型很简单。我有一个预定的活动,有参与者。我需要知道每个活动有多少参与者。

我对此的解决方案是添加一个 CTE,将已安排的事件分组并计算参与者的数量。

这将允许我加入每个预定活动的信息。保持查询简单。

我喜欢让我的查询保持简单,但是,如果我将来需要在我的简单查询期间访问其他临时结果,我该怎么办?

我真的很喜欢,如果我可以拥有多个 CTE 但我不能,对吧?我在这里有什么选择?

我已经排除了应用程序数据层的视图和处事。我更喜欢隔离我的 SQL 查询。

【问题讨论】:

    标签: sql-server tsql common-table-expression


    【解决方案1】:

    您可以在一个查询中拥有多个CTEs,也可以重复使用CTE

    WITH    cte1 AS
            (
            SELECT  1 AS id
            ),
            cte2 AS
            (
            SELECT  2 AS id
            )
    SELECT  *
    FROM    cte1
    UNION ALL
    SELECT  *
    FROM    cte2
    UNION ALL
    SELECT  *
    FROM    cte1
    

    但是请注意,SQL Server 可能会在每次访问 CTE 时重新评估它,因此如果您使用 RAND()NEWID() 等值,它们可能会在 CTE 调用之间发生变化。

    【讨论】:

    • 就是这么简单。 MSDN 文档对这个问题有点模糊,我找不到任何结论性的东西。非常感谢!
    • 它记录在WITH common_table_expression (Transact-SQL) 中。您可以在语法部分看到这一点(特别注意 [ WITH <common_table_expression> [ ,...n ] ] 中的 [ ,...n ]。示例 C,“在单个查询中使用多个 CTE 定义”明确指出了这一点。遗憾的是,此示例未在SQL 2008 及更早版本的文档(即,当 OP 发布问题时未提供示例)。
    • 我得到了双倍的记录:/
    • @TomStickel 尝试只使用查询的一半,在最后一个UNION ALL之前
    • @Quassnoi 是的。我在写完评论后就这样做了。不知道为什么第二个工会甚至在那里......
    【解决方案2】:

    您当然可以在一个查询表达式中包含多个 CTE。你只需要用逗号分隔它们。这是一个例子。在下面的示例中,有两个 CTE。一个名为CategoryAndNumberOfProducts,第二个名为ProductsOverTenDollars

    WITH CategoryAndNumberOfProducts (CategoryID, CategoryName, NumberOfProducts) AS
    (
       SELECT
          CategoryID,
          CategoryName,
          (SELECT COUNT(1) FROM Products p
           WHERE p.CategoryID = c.CategoryID) as NumberOfProducts
       FROM Categories c
    ),
    
    ProductsOverTenDollars (ProductID, CategoryID, ProductName, UnitPrice) AS
    (
       SELECT
          ProductID,
          CategoryID,
          ProductName,
          UnitPrice
       FROM Products p
       WHERE UnitPrice > 10.0
    )
    
    SELECT c.CategoryName, c.NumberOfProducts,
          p.ProductName, p.UnitPrice
    FROM ProductsOverTenDollars p
       INNER JOIN CategoryAndNumberOfProducts c ON
          p.CategoryID = c.CategoryID
    ORDER BY ProductName
    

    【讨论】:

    • @JohnLeidegren:在第一个正确答案后 2 分钟内发布正确答案值得投票,至少我已经给出了。
    • 如果其中一个是递归 cte 怎么办?有什么特别的顺序需要遵守吗?
    猜你喜欢
    • 1970-01-01
    • 2016-05-16
    • 2012-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多