【问题标题】:Using a CTE which calls another CTE - Incorrect syntax near ;使用调用另一个 CTE 的 CTE - 附近的语法不正确;
【发布时间】:2014-05-02 20:13:44
【问题描述】:

我正在尝试创建一个调用另一个 CTE 的 CTE,如下所示。但我得到这个错误:

消息 102,级别 15,状态 1,第 54 行 ';' 附近的语法不正确。

我真的看不出问题出在哪里。我检查了一堆与我类似的其他问题并尝试了这些问题的解决方案,但由于某种原因它不起作用。

With SEASONALITY_AVG_REVENUE
(
    YearKey
    ,Aggregation_Key
    ,Yearly_Avg_Revenue
)   
as
(
    SELECT
        ts.YearKey,
        agg.Aggregation_Key,
        Yearly_Avg_Revenue = AVG(agg.Revenue)

    FROM 
        seasonality_custom.TIME_SERIES_INDEX ts
        INNER JOIN seasonality_custom.SEASONALITY_AGG_TIME_SERIES agg
        ON ts.TIME_SERIES_INDEX = agg.TIME_SERIES_INDEX
    GROUP BY
        ts.YearKey,
        agg.Aggregation_Key  
)
, SEASONALITY_ALL_RECS
(
    YearKey
    ,Aggregation_Key
    ,Revenue
    ,Yearly_Avg_Revenue
)   
as
(
    SELECT
        ts.YearKey,
        agg.Aggregation_Key,
        agg.Revenue,
        Yearly_Avg_Revenue = savg.Yearly_Avg_Revenue
    FROM 
        seasonality_custom.TIME_SERIES_INDEX ts
        INNER JOIN seasonality_custom.SEASONALITY_AGG_TIME_SERIES agg
        ON ts.TIME_SERIES_INDEX = agg.TIME_SERIES_INDEX
        INNER JOIN SEASONALITY_AVG_REVENUE savg
        ON ts.YearKey = savg.YearKey and agg.Aggregation_Key = savg.Aggregation_Key
);

【问题讨论】:

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


    【解决方案1】:

    您不能拥有with 语句,除非您在其后跟一些其他语句,通常是select,但在许多数据库中update 和delete 也是如此。

    您的语句有多个 CTE,但它没有主要查询部分。错误在分号上,因为这会终止查询。

    【讨论】:

      【解决方案2】:

      你真的需要一个 CTE

      ; With SEASONALITY_AVG_REVENUE(YearKey, Aggregation_Key, Yearly_Avg_Revenue)   
      AS
       (
      SELECT  ts.YearKey,
              agg.Aggregation_Key,
              Yearly_Avg_Revenue = AVG(agg.Revenue)
      
      FROM seasonality_custom.TIME_SERIES_INDEX ts INNER JOIN 
      seasonality_custom.SEASONALITY_AGG_TIME_SERIES agg
      ON ts.TIME_SERIES_INDEX = agg.TIME_SERIES_INDEX
      GROUP BY ts.YearKey, agg.Aggregation_Key  
        )
      
      SELECT ts.YearKey,
              agg.Aggregation_Key,
              agg.Revenue,
              Yearly_Avg_Revenue = savg.Yearly_Avg_Revenue
      FROM seasonality_custom.TIME_SERIES_INDEX ts
      INNER JOIN  seasonality_custom.SEASONALITY_AGG_TIME_SERIES agg
      ON ts.TIME_SERIES_INDEX = agg.TIME_SERIES_INDEX
      INNER JOIN SEASONALITY_AVG_REVENUE savg
      ON ts.YearKey = savg.YearKey and  agg.Aggregation_Key = savg.Aggregation_Key
      

      或者

      正如 Gordon 提到的,CTE 后面需要跟一个 SELECT、UPDATE、DELETE 语句。

      使用您当前的查询,您只需在第二个 CTE 的末尾进行选择,它也会返回相同的结果,但这将是一个不必要的步骤。像这样的..

      ;WITH CTE1 (Col1, Col2)
      AS 
        (
          -- Some code here
        ),
      CTE2
      AS 
        (
           -- Some code here
        )
      SELECT * FROM CTE2
      

      【讨论】:

      • ; 应该放在语句的结尾,而不是开头。
      • CTE 是 SQL Server 中仅有的两种情况之一,其中要求前一条语句以 ; 终止,因此许多 SQL 开发人员养成了使用 @ 启动 CTE 的习惯987654327@ ,以; 终止语句在SQL Developers 中并不常见。因此坏/奇怪的习惯:)
      • 坚持这个坏习惯会让人们认为关键字是;with,并导致各种奇怪的问题,如this。甚至微软也建议使用;终止所有查询(参见例如here)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-02-07
      • 2014-08-03
      • 1970-01-01
      • 1970-01-01
      • 2013-01-11
      • 1970-01-01
      • 2020-04-01
      相关资源
      最近更新 更多