第104回 Oracleのお勉強 GROUP BY の罠

日付でGROUP BYするときは注意が必要

日付でGROUP BYするときは注意が必要である、
なぜなら時分秒まで持っている場合、時分秒まで加味してGROUP BYされるかれである。

テーブル作成, テーブルにデータINSERT
create table t_group_date(
  d_create  DATE,
  c_status  char(2)
);
insert into t_group_date
( d_create, c_status ) values ( to_date('2009/01/01 10:10:10', 'YYYY/MM/DD HH24:MI:SS'), 5 );

insert into t_group_date
( d_create, c_status ) values ( to_date('2009/01/01 10:10:11', 'YYYY/MM/DD HH24:MI:SS'), 5 );

insert into t_group_date
( d_create, c_status ) values ( to_date('2009/01/02 10:10:10', 'YYYY/MM/DD HH24:MI:SS'), 5 );

insert into t_group_date
( d_create, c_status ) values ( to_date('2009/01/02 10:10:11', 'YYYY/MM/DD HH24:MI:SS'), 0 );
SQL> select
  2    d_create     日付,
  3    c_status     ステータス
  4  from
  5    t_group_date
  6  ;

日付     ステータス
-------- --------------------
09-01-01 5
09-01-01 5
09-01-02 5
09-01-02 0

select の結果は、時分秒まで見えていないが、
Oracleは時分秒まで実は知っている、たんに表示されていないだけだ。

日付でGROUP BY
SQL> select
  2    d_create            日付,
  3    count(*)            件数
  4  from
  5    t_group_date
  6  group by
  7    d_create
  8  order by
  9    d_create
 10  ;

日付           件数
-------- ----------
09-01-01          1
09-01-01          1
09-01-02          1
09-01-02          1

この通り
09-01-01 が 2レコード、
09-01-02 が 2レコード出てしまっている。
時分秒が違うので別のグループになってしまったからだ。

日付を「日にち」単位でGROUP BY
SQL> select
  2    to_char(d_create, 'YYYY/MM/DD')        日付,
  3    count(*)                               件数
  4  from
  5    t_group_date
  6  group by
  7    to_char(d_create, 'YYYY/MM/DD')
  8  order by
  9    to_char(d_create, 'YYYY/MM/DD')
 10  ;

日付                       件数
-------------------- ----------
2009/01/01                    2
2009/01/02                    2

TO_CHARで、日付までの出力にするとうまくいく。