mysql - 在子查询中排序

G. *_*nte 12 mysql sql subquery sql-order-by mariadb

我使用以下查询与MySQL 5.5(或以前的版本)多年没有任何问题:

SELECT t2.Code from (select Country.Code from Country order by Country.Code desc ) AS t2;
Run Code Online (Sandbox Code Playgroud)

结果的顺序总是在我需要的时候下降.

上周,我刚刚迁移到一个新的MySQL版本(事实上,我已迁移到MariaDB 10.0.14),现在使用相同数据库的相同查询不再按降序排序.它按升序排序(或使用自然顺序排序,实际上不确定).

那么,有人可以告诉我这是一个错误还是这是对MySQL/MariaDB最新版本中行为的改变?

谢谢.

G.普兰特

Mic*_*ski 22

经过一番挖掘,我可以确认你的两个场景:

MySQL 5.1确实应用ORDER BY了子查询内部.

在Linux上MariaDB的39年5月5日也不能适用ORDER BY无当子查询中LIMIT提供.但是,当给出相应的时,它确实正确地应用了订单LIMIT:

SELECT t2.Code 
FROM (
  SELECT Country.Code FROM Country ORDER BY Country.Code DESC LIMIT 2
) AS t2;
Run Code Online (Sandbox Code Playgroud)

没有它LIMIT,没有充分的理由在子查询中应用排序.它可以等效地应用于外部查询.

记录的行为:

事实证明,MariaDB已经记录了这种行为并且它不被视为错误:

FROM根据SQL标准,"表"(以及子句中的子查询)是一组无序行.表中(或FROM子句中的子查询中)的行不按任何特定顺序排列.这就是优化器可以忽略ORDER BY您指定的子句的原因.实际上,SQL标准甚至不允许ORDER BY子句出现在这个子查询中(我们允许它,因为ORDER BY ... LIMIT......更改结果,行集,而不仅仅是它们的顺序).

您需要将FROM子句中的子查询视为一组未指定和未定义的行,并将其ORDER BY放在顶层SELECT.

因此,MariaDB还建议ORDER BY在最外层的查询中应用,或者LIMIT在必要时应用.

注意:我目前无法访问正确的MySQL 5.5或5.6以确认其行为是否相同(并且SQLFiddle.com出现故障).对原始错误报告的评论(关闭为非bug)表明MySQL 5.6的行为可能与MariaDB相同.

  • “没有充分的理由在子查询内应用排序。它可以等效地应用于外部查询”废话。例如:要选择每个组的某个列的最大值或最小值,在 MySQL 中您应该能够执行:`SELECT t1.* FROM (SELECT * FROM table ORDER BY value_col DESC) AS t1 GROUP BY group_col` 来获取每个“group_col”的最大“value_col”。当我输入 ORDER BY 时,我希望数据库对其进行排序,无论他是否认为这是一个好主意。 (2认同)

小智 5

在较新版本的 MySQL 和 MariaDB 中,您可以通过应用 LIMIT 来强制子查询中的 ORDER BY。如果不想限制行数,请使用 BIGINT 的最大数量作为 LIMIT。

例如,当需要以所需的顺序生成子查询(例如用于应用行号)时,这有时可能会派上用场。