SQL CTE和ORDER BY影响结果集

Bre*_*ett 7 sql sql-server common-table-expression sql-server-2008

我在下面粘贴了一个非常简化的SQL查询版本.我遇到的问题是该ORDER BY语句影响了我的CTE的选择结果.我无法理解为什么会这样,我最初的想法是在CTE中,我执行一些SELECT声明,然后ORDER BY应该对THOSE结果起作用.

不幸的是,我看到的行为是我的内心SELECT陈述受到了订单的影响,给了我不属于TOP 10.

以下是数据示例:(按ID以相反顺序索引)

ID,   Date
9600  2010-10-12
9599  2010-09-08
9598  2010-08-31
9597  2010-08-31
9596  2010-08-30
9595  2010-08-11
9594  2010-08-06
9593  2010-08-05
9592  2010-08-02
....
9573  2010-08-10
....
8174  2010-08-05
....
38    2029-12-20
Run Code Online (Sandbox Code Playgroud)

我的基本查询:

;with results as(
select TOP 10 ID, Date
from dbo.items
)
SELECT ID
FROM results
Run Code Online (Sandbox Code Playgroud)

查询返回:

ID,   Date
9600  2010-10-12
9599  2010-09-08
9598  2010-08-31
9597  2010-08-31
9596  2010-08-30
9595  2010-08-11
9594  2010-08-06
9593  2010-08-05
9592  2010-08-02
Run Code Online (Sandbox Code Playgroud)

我的查询 ORDER BY

;with results as(
select TOP 10 ID, Date
from dbo.items
)
SELECT ID
FROM results
ORDER BY Date DESC
Run Code Online (Sandbox Code Playgroud)

查询返回:

ID,   Date
38    2029-12-20
9600  2010-10-12
9599  2010-09-08
9598  2010-08-31
9597  2010-08-31
9596  2010-08-30
9595  2010-08-11
9573  2010-08-10
9594  2010-08-06
8174  2010-08-05
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释为什么第一个查询只返回表中前10个的ID,第二个查询返回整个表的前10个(应用排序后).

Mar*_*ers 14

当您使用时SELECT TOP n,如果您想要确定性行为,则必须提供ORDER BY,否则服务器可以自由返回任何10行感觉.您看到的行为完全有效.

要解决此问题,请在CTE中指定ORDER BY:

WITH results AS
(
    SELECT TOP 10 ID, Date
    FROM dbo.items
    ORDER BY ID DESC 
)
SELECT ID
FROM results
ORDER BY Date
Run Code Online (Sandbox Code Playgroud)

  • @Brett - 您需要告诉数据库"表格中排名前10行"的含义.根据什么指标排名前10位?也许按日期排序? (2认同)
  • 正如马克所说,你在CTE之外的ORDER BY不影响结果,CTE内部的ORDER BY缺乏*会影响结果. (2认同)

小智 5

我认为您可以添加新列,例如

SELECT ROW_NUMBER() OVER(ORDER BY <ColumnName>;) AS RowNo
Run Code Online (Sandbox Code Playgroud)

然后是所有列.. 这将帮助您使用 CTE 锚点进行查询...使用 between、where 等子句..