保持简单以及如何在查询中执行多个CTE

Joh*_*ren 137 t-sql sql-server common-table-expression

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

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

我的解决方案是添加一个CTE,它对预定的事件进行分组并计算参与者的数量.

这将允许我按预定活动加入该信息.保持查询简单.

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

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

我已经在应用程序数据层排除了视图和操作.我更喜欢孤立我的SQL查询.

Qua*_*noi 262

您可以CTE在一个查询中使用多个s,并重用一个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
Run Code Online (Sandbox Code Playgroud)

但是请注意,这SQL Server可能会重新评估CTE其访问的每个时间,因此,如果您使用的是像价值观RAND(),NEWID()等等,它们可以在之间进行切换CTE通话.

  • 它记录在 [WITH common_table_expression (Transact-SQL)](http://msdn.microsoft.com/en-us/library/ms175972.aspx) 中。您可以在语法部分中看到这一点(请特别注意“[WITH <common_table_expression> [,...n ] ]”中的“[,...n ]”。示例 C,“在中使用多个 CTE 定义”一个单一的查询,”明确地指出了这一点。遗憾的是,SQL 2008 及更早版本的文档中没有提供这个示例(即,当 OP 发布问题时没有提供该示例)。 (3认同)
  • 就这么简单。MSDN文档对此问题有点模糊,我找不到任何结论。非常感谢你! (2认同)
  • @TomStickel 我的猜测是第二个联合只是为了说明 Quassnoi 的观点,即您可以重用 CTE。 (2认同)

Ran*_*der 77

您当然可以在单个查询表达式中拥有多个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
Run Code Online (Sandbox Code Playgroud)

  • @JohnLeidegren:在第一个正确答案的2分钟内发布一个正确的答案值得一个upvote,至少我已经给出了. (4认同)