Movatterモバイル変換


[0]ホーム

URL:


ひだまりソケットは壊れない

ソフトウェア開発に関する話を書きます。 最近は主に Android アプリ、Windows アプリ (UWP アプリ)、Java 関係です。

まじめなことを書くつもりでやっています。 適当なことは 「一角獣は夜に啼く」 に書いています。

この広告は、90日以上更新していないブログに表示しています。

MySQL では GROUP BY 句を使用した場合でも集約されていない列を結果に含めることができる

表題どおり。

普通、SQL で GROUP BY 句を使用して SELECT する場合、結果に含めることができる列は GROUP BY 句に含まれる列か集約関数 (aggregate functions) を適用した列のみです。 しかし、MySQL の場合はそうではなく、GROUP BY 句にも含まれていないし集約関数も通していない列を結果に含めることができます。

仕事で触ってるプログラムの中にそういうクエリを発行するSQL があって 「マジか!!」 って思ったのですが、調べてみるとパフォーマンスのためにそういう拡張がなされているとのことでした。

MySQL extends the use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal inMySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are indeterminate. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Sorting of the result set occurs after values have been chosen, and ORDER BY does not affect which values the server chooses.

http://dev.mysql.com/doc/refman/5.6/en/group-by-hidden-columns.html

CREATETABLE example_table ( a INT, b INT, c INT );

上のように作ったテーブルが存在する場合、列 a でグループ化してそれぞれの a の値に対する b の値の最大値を求めるクエリは下のようになります。 このSQLPostgreSQL でもMySQL でも普通に結果を返してくれます。

SELECT a, MAX(b)FROM example_tableGROUPBY a;

さらに、結果に列 c を含めようとすると、下のようなクエリになります。

SELECT a, MAX(b), cFROM example_tableGROUPBY a;

PostgreSQL でこのクエリを投げると、列 c が GROUP BY にも含まれないし集約関数を通しているわけでもないので以下のようにエラーになります。 (PostgreSQL 9.1 で確認。)

ERROR:  column "example_table.c" must appear in the GROUP BY clause or be used in an aggregate functionLINE 1: SELECT a, MAX(b), c FROM example_table GROUP BY a;                          ^

一方でMySQL の場合はエラーにならずに結果を返してくれます。 (MySQL 5.5 で確認。)MySQL サーバーは、集約されていない列の値に関しては各グループの中から自由に選ぶ (The server is free to choose any value from each group) とのことです。

ONLY_FULL_GROUP_BY モード (追記)

集約関数を通していない値が結果に含まれるようなSQL を拒否させるためのONLY_FULL_GROUP_BY というSQL MODE があります。 5.7.5 以降ではデフォルトで有効になっているみたいですね。

注目記事
検索
最近のコメント
    カテゴリー

    引用をストックしました

    引用するにはまずログインしてください

    引用をストックできませんでした。再度お試しください

    限定公開記事のため引用できません。

    読者です読者をやめる読者になる読者になる

    [8]ページ先頭

    ©2009-2025 Movatter.jp