MySQLのGroup By句には別名を使うべきだ
select文でgroup byする時は、select句の中でグルーピング関数を使ってないとこをそのまんまgroup byにブチ込めば良いと覚えている人は多いと思う。例えば下記のように。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
SQLの意図:「2013年度に納品したプロジェクト数とそれ以外のプロジェクト数」を確認する。 select case when ( '2013-04-01' <= nouhinbi and nouhinbi <= '2014-03-31' ) then 1 else 0 end , count(*) from t_nouhinbi group by case when ( '2013-04-01' <= nouhinbi and nouhinbi <= '2014-03-31' ) then 1 else 0 end ; |
しかし、これだと保守性が悪い。プログラム変更時は、select句とgroup by句が常に一致するように修正しなければならないからだ。うっかりしてselect句だけを変更してしまうと、意図通りの結果が返ってこなくなる。
それに対応するため、group by句には別名を使うことを徹底すべきだ。例えば、下記のように。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
select case when ( '2013-04-01' <= nouhinbi and nouhinbi <= '2014-03-31' ) then 1 else 0 end as TounendoFlg , count(*) from t_nouhinbi group by TounendoFlg ; |
こうすれば、何かあった時の変更個所はselect句だけで済む。
特に、MySQLでは変なグルーピングをしてもエラーを吐いてくれないからタチが悪い。気を付けろ!
テスト用に、上記テーブルのダンプも載せておく。各自練習してみてくれ。
1 2 3 4 5 6 7 8 |
CREATE TABLE `t_nouhinbi` ( `PJCD` varchar(20) NOT NULL COMMENT 'プロジェクトコード', `Nouhinbi` date NOT NULL COMMENT '納品日', `UpdateDatetime` datetime NOT NULL COMMENT '更新日時', `UpdateNum` int(11) NOT NULL COMMENT '更新回数', PRIMARY KEY (`PJCD`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='PJ納品日テーブル'; INSERT INTO `t_nouhinbi` VALUES ('Kaihatsu1','2014-03-31','2015-08-07 00:00:00',1),('Kaihatsu10','2014-03-28','2015-08-07 00:00:00',1),('Kaihatsu11','2014-03-01','2015-08-07 00:00:00',1),('Kaihatsu12','2014-03-21','2015-08-07 00:00:00',1),('Kaihatsu13','2014-02-19','2015-08-07 00:00:00',1),('Kaihatsu14','2014-03-10','2015-08-07 00:00:00',1),('Kaihatsu15','2014-04-09','2015-08-07 00:00:00',1),('Kaihatsu2','2014-04-23','2015-08-07 00:00:00',1),('Kaihatsu3','2014-05-03','2015-08-07 00:00:00',1),('Kaihatsu4','2014-04-04','2015-08-07 00:00:00',1),('Kaihatsu5','2014-03-30','2015-08-07 00:00:00',1),('Kaihatsu6','2014-03-13','2015-08-07 00:00:00',1),('Kaihatsu7','2014-03-04','2015-08-07 00:00:00',1),('Kaihatsu8','2014-04-02','2015-08-07 00:00:00',1),('Kaihatsu9','2014-04-11','2015-08-07 00:00:00',1); |