【问题标题】:CTE top - order by clause is not always workingCTE top-order by 子句并不总是有效
【发布时间】:2014-04-01 15:03:26
【问题描述】:

我有以下 T-SQL 语句:

;WITH DataSource ([ColumnA]) AS
(
    SELECT TOP 100 [ColumnA] 
    FROM [dbo].[TEST] 
    WHERE [ColumnB] = 40 
    ORDER BY [ColumnC] DESC
)
SELECT [ColumnA]
      ,COUNT([ColumnA])
FROM DataSource
GROUP BY [ColumnA]

这根本不是返回相同的结果。我无法理解方式,但有时 CTE 中的 T-SQL 语句没有返回正确的值是因为产生了不同的结果,不是每次,而是有时(更准确地说,我得到三个不同的结果) .

如果我只执行以下语句:

SELECT TOP 100 [ColumnA] 
FROM [dbo].[TEST] 
WHERE [ColumnB] = 40 
ORDER BY [ColumnC] DESC

我每次都得到相同的结果。如果我使用派生表也没有问题:

SELECT [ColumnA]
      ,COUNT([ColumnA])
FROM
(
    SELECT TOP 100 [ColumnA] 
    FROM [dbo].[TEST] 
    WHERE [ColumnB] = 40 
    ORDER BY [ColumnC] DESC

) DataSource
GROUP BY [ColumnA]

谁能解释为什么 CTE 每次都没有返回正确的结果?

【问题讨论】:

  • ColumnC 是唯一的吗?如果不是,您将需要向ORDER BY 添加保证唯一的列,以充当决胜局以确保确定性结果。
  • 结果有什么问题?它是否返回(最多)100 行 ColumnB 等于 40 并且 ColumnC 值尽可能低?因为这就是它的全部保证。
  • @MartinSmith,不,它不是唯一的。有道理。
  • @Damien_The_Unbeliever 是的,你说得对——我到底在想什么……

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


【解决方案1】:

在 CTE 构造中不允许使用 ORDER BY。请在此处查看备注部分:MSDN。作为 CTE_QUERY_DEFINITION 的一部分提供 order by。我很惊讶 SQL Server 竟然让你运行它。

【讨论】:

  • 来自您的链接:ORDER BY (except when a TOP clause is specified)
  • 哇,我完全错过了你的 TOP 声明。我很抱歉。你看到这个了吗? stackoverflow.com/questions/3924940/…
【解决方案2】:

正如Martin Smith 在他的评论中指出的那样:

ColumnC 是唯一的吗?如果不是,您将需要添加保证唯一性 列到 ORDER BY 以充当​​平局断路器,以确保 确定性结果。

CTE 本身没有问题 - 问题是我没有按 unique 列排序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-20
    • 2018-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    相关资源
    最近更新 更多