untitled .engineer

技術系のブログ(仮)

MySQLは5.7までGROUP BYにASCとかDESCとかをつけられていた話

本エントリの概要

  • MySQLは5.7までGROUP BYにASCとかDESCとかをつけられていたことに気づいたことと、他のRDBMSがどうかを調べてみたので書きます

きっかけ

  • MySQL5.5からMySQL8.0にバージョンアップしたらSyntaxエラーになるSQLがあったのでアプリのソースを見てみたら
    SELECT hoge FROM fuga GROUP BY hoge ASC;
    みたいに書いてあって、突然のASCにパーサーが怒ったんですね。
  • というか「今までそんなSQLを受け入れていたんかお前は」って感じですし、「そんなSQL書いてたんか俺らは」という感じです。

マニュアルを引いてみる

    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}
      [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_condition]

8.0ではこうなっています。
https://dev.mysql.com/doc/refman/8.0/en/select.html

    [WHERE where_condition]
    [GROUP BY {col_name | expr | position}, ... [WITH ROLLUP]]
    [HAVING where_condition]

つまり5.7→8.0での変更点ということになりますね。

そこで8.0の変更点の一覧を探したら確かにありました。
https://dev.mysql.com/doc/refman/8.0/en/mysql-nutshell.html#mysql-nutshell-removals

The deprecated ASC or DESC qualifiers for GROUP BY clauses are removed. Queries that previously relied on GROUP BY sorting may produce results that differ from previous MySQL versions. To produce a given sort order, provide an ORDER BY clause.


(翻訳)
GROUP BY句の非推奨のASCまたはDESC修飾子は削除されました。 以前にGROUP BYソートに依存していたクエリは、以前のMySQLバージョンとは異なる結果を生成する場合があります。 特定のソート順を作成するには、ORDER BY句を指定します。

「GROUP BY句の非推奨のASCまたはDESC修飾子」ってことは「いつからか非推奨になっていたのか」と思って探してみたら5.7での変更点に以下の記述が https://dev.mysql.com/doc/refman/5.7/en/mysql-nutshell.html#mysql-nutshell-deprecations

GROUP BY implicitly sorts by default (that is, in the absence of ASC or DESC designators), but relying on implicit GROUP BY sorting in MySQL 5.7 is deprecated. To achieve a specific sort order of grouped results, it is preferable to use To produce a given sort order, use explicit ASC or DESC designators for GROUP BY columns or provide an ORDER BY clause. GROUP BY sorting is a MySQL extension that may change in a future release; for example, to make it possible for the optimizer to order groupings in whatever manner it deems most efficient and to avoid the sorting overhead.


(翻訳)
GROUP BYはデフォルトで暗黙的にソートされます(つまり、ASCまたはDESC指定子がない場合)が、MySQL 5.7の暗黙的なGROUP BYソートに依存することは非推奨です。 グループ化された結果の特定のソート順を実現するには、特定のソート順を作成するには、GROUP BY列に明示的なASCまたはDESC指定子を使用するか、ORDER BY句を指定することをお勧めします。」 GROUP BYソートは、将来のリリースで変更される可能性があるMySQL拡張機能です。たとえば、オプティマイザが最も効率的と思われる方法でグループ化を順序付けできるようにし、ソートのオーバーヘッドを回避します。

「暗黙的な」のは非推奨になってるけど、「明示的な」のは非推奨だとは読み取れない。

まぁ別に文句をつける気はさらさらないです。 GA版の5.7.xxのどこかで非推奨になったのかもしれないし。

他のDBMS

  • まさかと思って他のRDBMSのマニュアルをわかる範囲で探してみましたが、少なくとも以下のRDBMSでは公式のドキュメントにありませんでした。
  • (面倒なのでそれぞれ検証はしてませんが、たぶんエラーになるでしょう。)

まとめ

  • ソートはORDER BY使え