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

職業プログラマの休日出勤

職業プログラマによる日曜自宅プログラミングや思考実験の成果たち。リアル休日出勤が発生すると更新が滞りがちになる。記事の内容は個人の意見であり、所属している(いた)組織の意見ではない。

MySQLのGroup By

MySQLの Group By でハマったのでメモ。

テスト用テーブルの定義(PostgreSQLでもMySQLでも動作OK)

create table hogehoge (
 id int primary key,
 classification varchar(10),
 value numeric(5)
);

テスト用データ

insert into hogehoge values (1, 'test', 100);
insert into hogehoge values (2, 'test', 200);
insert into hogehoge values (3, 'foo', 50);

正常なSQL

select classification, max(value)
from hogehoge
group by classification;

よくあるSQL

PostgreSQLでの出力例
 classification | max 
----------------+-----
 foo            |  50
 test           | 200
(2 rows)

想定通りの結果。

MySQLでの出力例
+----------------+------------+
| classification | max(value) |
+----------------+------------+
| foo            |         50 |
| test           |        200 |
+----------------+------------+
2 rows in set (0.00 sec)

想定通りの結果。PostgreSQLの結果とも一致。

異常なSQL文

select classification, value
from hogehoge
group by classification;

"value"ではgroup化していないにも関わらず、"value"をselectしている点でおかしい。

PostgreSQLでの出力例
ERROR:  column "hogehoge.value" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: select classification, value
                               ^

想定通りエラーを返してくる。

MySQLでの出力例
+----------------+-------+
| classification | value |
+----------------+-------+
| foo            |    50 |
| test           |   100 |
+----------------+-------+
2 rows in set (0.00 sec)

あれれれれ?????


感想

MySQLはこの異常なSQLを投げてもエラーにしないらしい。
こんな方法で "value" を取得しても、そんなデータは役に立たないだろうに。
(そのせいで、今日は1時間以上「変なデータ」と格闘してしまった)

とても気になって MySQL5.1のマニュアル を見たら、こう書いてあった。

MySQL extends the use of GROUP BY to permit selecting fields that are not mentioned in the GROUP BY clause.

http://dev.mysql.com/doc/refman/5.1/en/select.html

わざとか。。

動作確認環境