2

我回答了这个问题:https : //stackoverflow.com/a/18521684/1707323,查询类似于:

SELECT
  *
FROM
  (
    SELECT
      *
    FROM
      table_name
    WHERE
      table_name.some_field='1' OR
      table_name.some_field='2'
    ORDER BY
      table_name.some_field
  ) sub_query
GROUP BY
  sub_query.primary_key_column

并发表了评论

聪明的想法,但这不能保证在 MySQL 中工作,并且会在 SQL Server 和大多数其他数据库系统中导致硬错误。从 Extensions 引用到 GROUP BY:“服务器可以从每个组中自由选择任何值,因此除非它们相同,否则选择的值是不确定的。此外,添加 ORDER BY 不会影响从每个组中选择值条款。

对于您的特定版本的 MySQL,对于您的特定表,它完全有可能始终为您提供您想要的结果,因为您获得的查询计划会导致您的查询以您期望的方式执行。但是,如果文档明确指出它将不确定地选择一个值,并且您的 ORDER BY 不足以使此查询可靠,那么在其他数据库或其他版本的 MySQL 上尝试此操作时我会非常谨慎。

MySQl 手册还继续说:Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values within each group the server chooses.对于诸如

SELECT
  *
FROM
  table_name
WHERE
  table_name.some_field='1' OR
  table_name.some_field='2'
GROUP BY
  table_name.primary_key_column
ORDER BY
  table_name.some_field

但这与子查询中带有 order by 子句的查询不同。我确实找到了类似的问题,但它再次不涉及子查询中的 ORDER BY 子句

任何人都可以参考 MySQL 手册对此有所了解ORDER BY,子查询中的子句是否会强制分组始终使用该组的第一个实例。

编辑:观察

FIFO 或 LIFO不应该与 GROUP BY 的操作方式有关吗?我就是想不通:

服务器可以从每个组中自由选择任何值

这种选择必须有某种逻辑。在没有某种指令的情况下,不允许计算机自行做出选择。如果计算机可以在没有任何指令的情况下自行做出选择,那么我们就真正达到了计算的最终目标,即人工智能,现在计算机可以通过给应用程序一个指令来编写我的所有代码。[LOL] 这是无证逻辑的可能性有多大?逻辑中的 RAND 不会比 FIFO 或 FILO 占用更多的处理能力吗?这里必须涉及一些逻辑,这些逻辑可能只是没有记录,但 100% 的时间都有效。我一直喜欢的一件事是几何证明。我知道你必须证明它是对还是错。我可以证明它是如何工作的,但我还没有看到它是如何工作的。

4

1 回答 1

1

不会。内联视图中的AnORDER BY不会强制GROUP BY外部查询中的操作从组中的“第一”行获取非聚合值。MySQL 可以自由地从组中选择任何行。

您可能会观察到会发生这种情况,但不能保证这种行为。

使用不同的数据库引擎、补丁集或更新版本的 MySQL,行为可能会有所不同,或者可能仅随着表中的值分布而改变。


跟进

(基于更新的问题)

SQL(结构化查询语言)背后的想法是它是声明性的,因为它声明要返回的结果集,并且没有指定“如何”返回结果集。

您非常正确,编写良好的代码本质上不是“随机的”,它遵循一组规则执行,并且我们观察到一致的行为。但是,这并不能保证这种行为永远不会改变。(编译器实现优化,导致机器代码给出相同的结果,但操作不同。)

多年来,当我们GROUP BY在 Oracle 中做 a 时,我们观察到 Oracle 将使用排序操作作为它“如何”满足GROUP BY. 每次我们运行相同的查询时,Oracle 都会进行相同的排序。但 Oracle 从未保证始终使用排序操作。

当推出新版本的 Oracle 时,你瞧,我们观察到 Oracle 现在使用散列操作而不是排序操作来满足 GROUP BY。任何包含ORDER BY子句的查询都会继续以指定的顺序返回结果(保证行为),但其他不包含子句的查询ORDER BY以不同的顺序返回行。Oracle 只是改进了“如何”准备满足要求的结果集。

这个例子说明了为什么我们不编写依赖于无法保证的行为的查询。

在以后的 MySQL 版本中,我们可能会观察到行为的变化,查询返回的结果集保证符合规范,但与当前返回的结果集不同。

SQL 的主要设计目标之一是我们声明要返回结果集,而不指定 DBMS “如何”生成结果集。我们确实使用了提示,并且我们以某种方式构建查询,这确实会影响优化器生成的执行计划。但这不是保证

如果结果集要满足指定的要求,则 SQL 应包含该规范;我们不应该依赖特定观察到的行为来暗示该规范。

于 2013-08-30T05:49:12.630 回答