我将以下查询与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中行为的改变?
经过一点挖掘,我可以确认您的两种情况:
MySQL 5.1确实ORDER BY在子查询中应用了内部。
ORDER BY
如果未提供,则Linux上的MariaDB 5.5.39 不会 应用ORDER BY内部子查询LIMIT。但是,当给出相应的命令时,它 会 正确应用订单LIMIT:
LIMIT
SELECT t2.Code FROM ( SELECT Country.Code FROM Country ORDER BY Country.Code DESC LIMIT 2 ) AS t2;
如果没有LIMIT,没有一个很好的理由来应用子查询中的排序。它可以等效地应用于外部查询。
事实证明,MariaDB已记录了此行为,并且不将其视为错误:
FROM根据SQL标准,“表”(子句中也包含子查询)是无序的行集。表(或FROM子句中的子查询)中的行不按任何特定顺序排列。这就是为什么优化器可以忽略ORDER BY您指定的子句的原因。实际上,SQL标准甚至不允许ORDER BY子句出现在该子查询中(我们允许它,因为ORDER BY ... LIMIT…更改了结果,行的集合,而不仅仅是行的顺序)。 您需要将FROM子句中的子查询视为一组未指定且未定义的行,并将其ORDER BY放在顶层SELECT。
FROM根据SQL标准,“表”(子句中也包含子查询)是无序的行集。表(或FROM子句中的子查询)中的行不按任何特定顺序排列。这就是为什么优化器可以忽略ORDER BY您指定的子句的原因。实际上,SQL标准甚至不允许ORDER BY子句出现在该子查询中(我们允许它,因为ORDER BY ... LIMIT…更改了结果,行的集合,而不仅仅是行的顺序)。
FROM
ORDER BY ... LIMIT
您需要将FROM子句中的子查询视为一组未指定且未定义的行,并将其ORDER BY放在顶层SELECT。
SELECT
因此,MariaDB还建议ORDER BY在最外面的查询中应用,或LIMIT在必要时应用。
注意:我目前无法访问适当的MySQL 5.5或5.6,以确认那里的行为是否相同(并且SQLFiddle.com出现故障)。对原始错误报告的评论(以非错误关闭)表明MySQL 5.6的行为方式可能与MariaDB相同。