mysql - 在子查询中排序

时间:2014-10-15 00:18:01

标签: 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;

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

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

那么,有人可以告诉我这是否是一个错误,或者这是否是最近版本的MySQL / MariaDB中的行为更改?

谢谢。

-G。普兰特

2 个答案:

答案 0 :(得分:19)

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

MySQL 5.1确实在子查询中应用了ORDER BY

Linux上的MariaDB 5.5.39在没有提供ORDER BY的情况下 not 在子查询中应用LIMIT。但确实会在给出相应的LIMIT时正确应用订单:

SELECT t2.Code 
FROM (
  SELECT Country.Code FROM Country ORDER BY Country.Code DESC LIMIT 2
) AS t2;

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

记录行为:

事实证明,MariaDB has documented this behavior并不认为它是一个错误:

  

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

     

您需要将FROM子句中的子查询视为一组未指定和未定义的行,并将ORDER BY放在顶级SELECT。< / p>

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

注意:我目前无法访问正确的MySQL 5.5或5.6以确认其行为是否相同(并且SQLFiddle.com出现故障)。 Comments on the original bug report(关闭为非bug)表明MySQL 5.6的行为可能与MariaDB相同。

答案 1 :(得分:0)

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

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