为什么SQL Server 2008在使用GROUP BY时订购并且没有指定订单?

Nat*_*mer 4 sql group-by sql-order-by sql-server-2008

我遇到了一个非常奇怪的问题,我还没有找到任何解释.使用SQL Server 2008并使用GROUP BY,它会在没有指定任何ORDER BY的情况下对我的列进行排序.这是一个演示这种情况的脚本.

CREATE TABLE #Values ( FieldValue varchar(50) )

;WITH FieldValues AS
(
    SELECT '4' FieldValue UNION ALL
    SELECT '3' FieldValue UNION ALL
    SELECT '2' FieldValue UNION ALL
    SELECT '1' FieldValue
)
INSERT INTO #Values ( FieldValue )
SELECT
    FieldValue 
FROM FieldValues

-- First SELECT demonstrating they are ordered DESCENDING
SELECT
    FieldValue
FROM #Values

-- Second SELECT demonstrating they are ordered ASCENDING
SELECT
    FieldValue
FROM #Values
GROUP BY
    FieldValue

DROP TABLE #Values
Run Code Online (Sandbox Code Playgroud)

第一个SELECT将返回

4
3
2
1
Run Code Online (Sandbox Code Playgroud)

第二个SELECT将返回

1
2
3
4
Run Code Online (Sandbox Code Playgroud)

根据MSDN文档,它声明:" GROUP BY子句不对结果集进行排序 "

Tad*_*mas 13

要回答这个问题,请查看两者生成的查询计划.

第一个SELECT是简单的表扫描,这意味着它按分配顺序生成行.由于这是一个新表,它与您插入记录的顺序相匹配.

第二个SELECT添加了一个GROUP BY,SQL Server通过一个不同的排序实现,因为估计的行数非常低.如果您有更多行或向SELECT添加聚合,此运算符可能会更改.

例如,尝试:

CREATE TABLE #Values ( FieldValue varchar(50) )

;WITH FieldValues AS
(
    SELECT '4' FieldValue UNION ALL
    SELECT '3' FieldValue UNION ALL
    SELECT '2' FieldValue UNION ALL
    SELECT '1' FieldValue
)
INSERT INTO #Values ( FieldValue )
SELECT
    A.FieldValue
FROM FieldValues A
CROSS JOIN FieldValues B
CROSS JOIN FieldValues C
CROSS JOIN FieldValues D
CROSS JOIN FieldValues E
CROSS JOIN FieldValues F

SELECT
    FieldValue
FROM #Values
GROUP BY
    FieldValue

DROP TABLE #Values
Run Code Online (Sandbox Code Playgroud)

由于行数,这会变为哈希聚合,现在查询计划中没有排序.

如果没有ORDER BY,SQL Server可以按任何顺序返回结果,并且它返回的顺序是它认为最快速返回数据的方式的副作用.


Pab*_*ruz 6

如果未指定order by子句,SQLServer可以按任何顺序自由返回结果.

也许在您的特定查询中,它将返回有序的结果,但这并不意味着它在使用group by子句时总是会对resltsets进行排序.

也许(只是可能)它正在做一些哈希聚合来计算组,并且哈希表恰好按1,2,3,4排序.然后在哈希顺序中返回行...