当前位置: 首页 > 面试题库 >

为什么在使用GROUP BY且未指定任何顺序时SQL Server 2008为何顺序?

益富
2023-03-14
问题内容

我遇到了一个非常奇怪的问题,至今尚未找到任何解释。使用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

第一个SELECT将返回

4
3
2
1

第二个SELECT将返回

1
2
3
4

根据MSDN文档,它指出:“ GROUP
BY子句不对结果集进行排序


问题答案:

要回答此问题,请查看两者产生的查询计划。

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

第二个SELECT添加了GROUP BY,由于估计的行数非常低,因此SQL Server通过不同的排序来实现GROUP
BY。如果您有更多行或将聚合添加到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

由于行数的原因,这变成了哈希聚合,现在查询计划中没有排序。

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



 类似资料:
  • 问题内容: 我正在处理SQL Reporting Services报表(在VS.Net 2005中),该报表在矩阵中显示不同数据的数量。这些列对特定集合中的客户数量进行计数。因此,我有几个类似的列:“ 1个雇主”,“ 2-9个雇主”,“ 10-19个雇主”等等。 我的问题是SQL Reporting Services按字母顺序对矩阵中的列进行排序。因此,我最终在“ 1个雇主”列之后但在“ 2-9”

  • 问题内容: 我听说(在互联网上的某处阅读)比顺序IO快。它是否正确?如果是,那为什么会更快? 没有按顺序阅读。 已经从磁盘读取本身一样呢 映射区域不是顺序的-因此没有DMA(?)。 那么实际上应该比从文件慢吗?我上面的哪些假设是错误的? 问题答案: 我听说(在互联网上的某处阅读)mmap()比顺序IO更快。它是否正确?如果是,那为什么会更快? 可能是-有优点和缺点,如下所列。 当您真的有理由要关心

  • 问题内容: 我对CSS和属性有些困惑。我一直认为,在属性值中指定多个类的顺序具有一定的意义。后一类可以/应该覆盖前一类的定义,但这似乎不起作用。这是一个例子: 我希望第三个示例使用蓝色边框,因为额外指定的边框会覆盖基本边框。 我在ubuntu 9.04上使用FF 3 问题答案: 属性被覆盖的顺序不是由类在属性中定义的顺序决定的,而是由它们在CSS中出现的位置决定的。 在该文本将出现,而不是; 因为

  • 问题内容: 我有一个使用Mockito的测试,它的行为非常奇怪:它可以在调试中工作,但在正常运行时会失败。经过一番调查后,我意识到这是因为我在模拟方法行为,传递了要匹配的元素列表。但是由于某些原因,列表中的顺序并不总是相同,因此不匹配,并且我的模拟返回的结果也不会返回,因为2个列表不是“等于” 就我而言,匹配元素的顺序无关紧要。那么在配置模拟时如何指定呢? 问题答案: 这是单线的。使用Hamcre

  • 问题内容: 什么是“序列点”? 未定义行为与序列点之间有什么关系? 我经常使用诸如的有趣且令人费解的表情a[++i] = i;来使自己感觉更好。为什么我应该停止使用它们? 问题答案: C 98和C 03 此答案适用于C 标准的较旧版本。该标准的C 11和C ++ 14版本没有正式包含“序列点”。操作是“先于”或“未排序”或“不确定地排序”。最终效果基本相同,但是术语不同。 免责声明:好的。这个答案

  • 关于SO的两个主题解释了C++11上下文中的这些示例。这里说调用UB,定义良好。这里说这两个例子都没有定义。这种模棱两可让我很困惑。这篇结构良好的参考文献我已经读了三遍了,但是这个主题对我来说似乎太复杂了。 . 让我们分析示例:。 相应的报价有: > 内置的预增量和预减量运算符的副作用在其值计算之前被排序(由于定义为复合赋值而导致的隐式规则) 内建赋值运算符和所有内建复合赋值运算符的副作用(左参数