【问题标题】:TSQL-ORDER BY clause in a CTE expression?CTE 表达式中的 TSQL-ORDER BY 子句?
【发布时间】:2018-04-20 15:05:07
【问题描述】:

我们可以在 CTE 表达式中使用ORDER BY 子句吗?

;with y as
(
     select 
         txn_Date_Time, txn_time, card_No, batch_No, terminal_ID
     from 
         C1_Transaction_Information
     where 
         txn_Date_Time = '2017-10-31'
     order by 
         card_No
)
select * from y;

错误信息:

消息 1033,第 15 级,状态 1,第 14 行
ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。

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

【问题讨论】:

  • 显然,你不能。我认为错误消息几乎可以回答您的问题。
  • 不,除非您指定 TOP,否则您不能。为什么要对 CTE 进行排序?
  • 这是什么问题,他们明确表示“ORDER BY 子句在视图、内联函数、派生表、子查询和公用表表达式中无效,除非还指定了 TOP、OFFSET 或 FOR XML。 ”。你不能在那里使用
  • 错误消息已经告诉您不,并且告诉您可以进行哪些更改以允许它。如果您有问题,则不清楚错误消息未涵盖您要问的内容。

标签: sql sql-server tsql stored-procedures


【解决方案1】:

您不能在 CTE 中使用“Order By”,但您可以将 order by 移动到调用 CTE 的 select 语句中,并产生我相信您正在寻找的效果

;with y as(
select txn_Date_Time,txn_time,card_No,batch_No,terminal_ID
from C1_Transaction_Information
where txn_Date_Time='2017-10-31'

)

select * from y order by card_No;

【讨论】:

    【解决方案2】:

    仅供参考 https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expression-transact-sql

    以下子句不能在 CTE_query_definition 中使用:

    ORDER BY(指定 TOP 子句时除外)

    进入

    带有查询提示的OPTION子句

    浏览

    【讨论】:

      【解决方案3】:

      一个不错的选择是在 CTE 中使用 ROW_NUMBER:

      ;with y as
      (
           select  
               rn = ROW_NUMBER() OVER (ORDER BY card_No),
               txn_Date_Time, 
               txn_time, 
               card_No, 
               batch_No, 
               terminal_ID
           from 
               C1_Transaction_Information
           where 
               txn_Date_Time = '2017-10-31'
      )
      select txn_Date_Time, 
               txn_time, 
               card_No, 
               batch_No, 
               terminal_ID
      from y 
      order by rn;
      

      这使您可以选择 TOP 10 作为 TOP ...ORDER BY 在 CTE 中是不允许的:

      ;with y as
      (
           select  
               rn = ROW_NUMBER() OVER (ORDER BY card_No),
               txn_Date_Time, 
               txn_time, 
               card_No, 
               batch_No, 
               terminal_ID
           from 
               C1_Transaction_Information
           where 
               txn_Date_Time = '2017-10-31'
      )
      select txn_Date_Time, 
               txn_time, 
               card_No, 
               batch_No, 
               terminal_ID
      from y 
      where rn <= 10;
      

      【讨论】:

      • 正是我需要的!谢谢!
      【解决方案4】:

      如果 cte 提供 JSON,您可以在 cte 中使用 ORDER BY

      WITH cte(n) AS (
          SELECT 1
          UNION ALL
          SELECT 2
      ), cte2(j) AS (
          SELECT n 
          FROM cte
          ORDER BY n
          FOR JSON PATH
      )
      SELECT * FROM cte2;
      

      理由是您可以在最终输出中使用 ORDER BY。在最终输出之前,您可以保留稍后调用排序所需的列。

      【讨论】:

        猜你喜欢
        • 2017-05-04
        • 2014-04-01
        • 1970-01-01
        • 2018-06-12
        • 2013-10-11
        • 2013-08-30
        • 2012-12-07
        • 1970-01-01
        • 2017-12-07
        相关资源
        最近更新 更多