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可以按任何顺序返回结果,并且它返回的顺序是它认为最快速返回数据的方式的副作用.
如果未指定order by子句,SQLServer可以按任何顺序自由返回结果.
也许在您的特定查询中,它将返回有序的结果,但这并不意味着它在使用group by子句时总是会对resltsets进行排序.
也许(只是可能)它正在做一些哈希聚合来计算组,并且哈希表恰好按1,2,3,4排序.然后在哈希顺序中返回行...