SELECT DISTINCT 是不是暗示某种结果

Posted

技术标签:

【中文标题】SELECT DISTINCT 是不是暗示某种结果【英文标题】:Does SELECT DISTINCT imply a sort of the resultsSELECT DISTINCT 是否暗示某种结果 【发布时间】:2009-03-27 21:39:29 【问题描述】:

在 SELECT 查询中包含 DISTINCT 是否意味着应该对结果集进行排序?

我不认为是这样,但我正在寻找一个权威的答案(网络链接)。

我有一个这样的查询:

Select Distinct foo
From Bar

在 oracle 中,结果是不同的,但不是按顺序排列的。在 Jet/MS-Access 中,似乎需要做一些额外的工作来确保对结果进行排序。我假设 oracle 在这种情况下遵循规范,而 MS Access 正在超越。

另外,有没有办法给表格一个提示,它应该在foo 上排序(除非另有说明)?

【问题讨论】:

【参考方案1】:

来自SQL92 specification:

如果指定了 DISTINCT,则令 TXA 为从 TX 中消除冗余重复值的结果。否则,令 TXA 为 TX。

...

4) 如果未指定 an,则 Q 的行的顺序取决于实现。

最终真正的答案是 DISTINCT 和 ORDER BY 是 SQL 语句的两个独立部分;如果您没有 ORDER BY 子句,则定义的结果将不会被具体排序。

【讨论】:

【参考方案2】:

没有。在许多情况下,Oracle 中的 DISTINCT 并不意味着排序,其中最重要的是 10g+ 中用于 group by 和 distinct 操作的散列算法。

始终如果您想要一个有序的结果集,请指定 ORDER BY,即使在 9i 及以下版本中也是如此。

【讨论】:

我认为这不能回答问题。当然,如果您想要两者,则必须同时指定两者。但是无论您请求的排序(或不排序)如何,都会根据 DISTINCT 执行排序吗? 问:“在 SELECT 查询中包含 DISTINCT 是否意味着应该对结果集进行排序?”答:“在许多情况下,Oracle 中的 DISTINCT 并不意味着排序”在 10g 之前,DISTINCT 结果集通常会被排序,但并非总是如此。【参考方案3】:

没有“权威”的答案链接,因为这是没有 SQL 服务器保证的。

当使用 distinct 作为查找这些结果的最佳方法的副作用时,您经常会看到按顺序排列的结果。但是,任何数量的其他事情都可能混淆结果,并且某些服务器可能会以不给它们排序的方式交回结果,即使它必须排序才能获得结果。

底线:如果你的服务器不能保证你不应该指望它。

【讨论】:

【参考方案4】:

据我所知,没有。我能想到的唯一原因是 SQL Server 会在内部对数据进行排序以检测和过滤掉重复项,从而以“预先排序”的方式返回它。但我不会依赖那个“副作用”:-)

【讨论】:

【参考方案5】:

不,这并不意味着排序。根据我的经验,它按已知索引排序,可能恰好是 foo。

为什么要微妙?为什么不具体 Select Distinct foo from Bar Order by foo?

【讨论】:

怎么样,因为这不是您想要的顺序? 在他的帖子“对 foo 进行排序(除非另有说明)”中,我问为什么不指定 foo,除非另有说明 为什么要微妙和暗示?我只是不想在这一点上重新编译和重新部署。如果我能给 oracle 一个提示,它会解决我的问题,我可以在更方便的时候进行显式修复。 啊……嗯,有道理。 “给表一个提示”是什么意思?我从来没有听说过在表上加上提示,只在 SQL 上。【参考方案6】:

在我使用过的至少一台服务器上(可能是 Oracle 或 SQL Server,大约六年前),如果您没有 ORDER BY 子句,则 SELECT DISTINCT 会被拒绝。它在“其他”服务器(Oracle 或 SQL Server)上被接受。您的里程可能会有所不同。

【讨论】:

【参考方案7】:

不,结果未排序。如果你想给它一个“提示”,你当然可以提供一个 ORDER BY:

选择不同的 foo 从酒吧 由 foo 订购

但请记住,您可能想要的不仅仅是按字母顺序排序。相反,您可能希望根据其他字段的标准进行排序。见:

http://weblogs.sqlteam.com/jeffs/archive/2007/12/13/select-distinct-order-by-error.aspx

【讨论】:

【参考方案8】:

正如大多数答案所说,DISTINCT 不强制要求排序 - 只有 ORDER BY 强制要求。但是,获得 DISTINCT 结果的一种标准方法是排序;另一种是散列值(这往往会导致半随机排序)。依赖 DISTINCT 的排序效果是愚蠢的。

【讨论】:

【参考方案9】:

以我的例子(SQL 服务器)为例,我有一个国家列表,每个国家都分配了一个数值 X。当我按 X 执行 select distinct * from Table order 时,它按 X 排序,但同时结果集国家也被排序,这不是直接实现的。 根据我的经验,我会说 distinct 确实意味着隐式排序。

【讨论】:

您能否添加一个代码示例(或将您的代码示例拆分为单独的段落)? @Jess Bowers:下面是 sn-p:顺便提一下 ABC 和 #result 都是在存储过程中调用的临时表:Insert into #Result select DISTINCT top (10) * rom ABC X order by X.Y asc select * from #Result【参考方案10】:

是的。 Oracle确实使用排序来计算不同的。如果你看一下解释计划,你就会看到。它对该计算进行了排序这一事实绝不意味着 结果集将被排序。如果要对结果集进行排序,则需要使用 ORDER BY 子句。

【讨论】:

Oracle 10 和 11 使用散列来计算不同的,而不是排序。 Oracle 10 和 11可能使用散列。 我可以相信。我在计划中观察到排序以响应不同。我卡在 9i 和 10g 上。

以上是关于SELECT DISTINCT 是不是暗示某种结果的主要内容,如果未能解决你的问题,请参考以下文章

SELECT DISTINCT 结果封装在 VIEW 中。

SQL如何先用group by分组,并将分组的结果distinct?

sql语法

MySQL_select distinct无法实现只对单列去重,并显示多列结果的解决方法

SELECT Count Distinct Syntax MS Access SQL [重复]

sql语句去重distinct方法是啥?