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

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

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

distinct と order by

MySQL PostgreSQL

きっと GROUP BY のときの話 と同じ理屈なんでしょうけど、困ってしまったので記事に書いておきます。

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

create table test20121028 (
  id int primary key,
  data1 text not null
);

insert into test20121028 values(1, 'aaa');
insert into test20121028 values(2, 'bbb');
insert into test20121028 values(3, 'bbb');
insert into test20121028 values(4, 'aaa');

困ったSQL

select distinct data1
from test20121028
order by id;

「data1の重複除去したデータを出力してね、id順に」と言ってる訳ですが、こんな馬鹿げたことを許してはなりませんよね。
PostgreSQLで実行すると、やはりエラーになります。

postgres=# select distinct data1
postgres-# from test20121028
postgres-# order by id;
ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 3: order by id;

MySQLで実行すると

mysql> select distinct data1
    -> from test20121028
    -> order by id;
+-------+
| data1 |
+-------+
| aaa   |
| bbb   |
+-------+
2 rows in set (0.01 sec)

動く。。。

過去の汚いSQL、どうする?

冒頭に掲げた記事で言及しているとおり、MySQLは故意にこのような汚いSQLの実行も認めている訳ですが、現在動いているシステムの中にこういったSQLがあるのであれば、ビシバシと治していきたいですよね。そう、治したくなるのが人情というものです。
今回の場合であれば、 order by min(id) とか、max(id) といった具合に。

で、汚いSQLを見つけ出す方法をいろいろ考えてはみたものの、上手く行かないですね。他のRDBMSで動かしてみる、というのも準備が非常に面倒臭い上に、正当にMySQL依存のSQLを利用しているところが難しいです。
やはり、見つけ次第治していくというのが現実的でしょうか。