MySQL/MariaDB - order by inside subquery

xfyts7mz  于 2023-04-10  发布在  Mysql
关注(0)|答案(3)|浏览(101)

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

SELECT t2.Code from (select Country.Code from Country order by Country.Code desc ) AS t2;

结果的顺序总是按我的需要降序排列。
上周,我刚刚迁移到一个新的MySQL版本(事实上,我迁移到MariaDB 10.0.14),现在同一个数据库的同一个查询不再是降序排序。它是升序排序(或者使用自然顺序排序,事实上不确定)。
那么,有人能告诉我这是一个bug,还是最近版本的MySQL/MariaDB的行为发生了变化?

dz6r00yl

dz6r00yl1#

经过一番挖掘,我可以确认你的两个场景:
MySQL 5.1确实在子查询中应用了ORDER BY
当没有提供LIMIT时,Linux上的MariaDB 5.5.39不会在子查询中应用ORDER BY。但是,当给出相应的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并不被视为bug:
一张“table”根据SQL标准,FROM子句中的子查询(以及子查询)是一组无序的行。(或在FROM子句的子查询中)不以任何特定的顺序出现。这就是为什么优化器可以忽略您指定的ORDER BY子句。实际上,SQL标准甚至不允许ORDER BY子句出现在这个子查询中(我们允许它,因为ORDER BY ... LIMIT...改变了结果,行的集合,而不仅仅是它们的顺序)。
您需要将FROM子句中的子查询视为一组未指定和未定义顺序的行,并将ORDER BY放在顶层SELECT上。
因此MariaDB还建议在最外面的查询中应用ORDER BY,或者在必要时应用LIMIT
注意:我目前无法访问适当的MySQL 5.5或5.6来确认那里的行为是否相同(并且SQLFiddle.com正在发生故障)。Comments on the original bug report(关闭为not-a-bug)表明MySQL 5.6可能与MariaDB的行为相同。

3yhwsihp

3yhwsihp2#

在较新版本的MySQL和MariaDB中,可以通过应用LIMIT来强制子查询中的ORDER BY。如果不想限制行,请使用BIGINT的最大数量作为LIMIT。
例如,当需要以期望的顺序生成子查询以应用行号时,这有时会派上用场。

cngwdvgl

cngwdvgl3#

使用order + limit insert子查询如下:

SELECT * FROM (
  SELECT * 
  FROM some_table 
  ORDER BY date DESC
  LIMIT 0,18446744073709551615
) AS a GROUP BY person
;

它将保持分组前的顺序。

相关问题