home | prev | next |
---|
例えば次の様なテーブルがあり、
create table item ( code char(8) constraint firstkey primary key, name varchar(64) not null, price int, count int );
その中に
code | name | price | count |
---|---|---|---|
01011001 | りんご | 100 | 5 |
01011002 | みかん | 100 | 5 |
01011003 | いちご | 100 | 10 |
01011004 | ばなな | 100 | 5 |
01011005 | かき | 100 | 1 |
01011006 | メロン | 300 | 1 |
というデータがあったとします。
price が 100円のレコード数と 300円のレコード数を個別に集計する時、どのような SQLを発行しますか?
レコード数を数えるなら通常 count関数を使用すると思います。
select count(price) from item where price = 100; select count(price) from item where price = 300;
price が 100円と 300円のレコード数なのでと上記の様に二回 SQLを発行するか、
select A.百円, B.三百円 from (select count(price) as 百円 from item where price = 100) A, (select count(price) as 三百円 from item where price = 300) B
と結合するか、
select count(price) from item where price = 100 union select count(price) from item where price = 300;
などと色々ありますが、何れも itemテーブルを 2回スキャンすることに変わりはありません。
ところが、case when then 〜 end を使用した場合、itemテーブルは 1回しかスキャンすることはありません。
select coalesce(sum(case when price = 100 then 1 else 0 end), 0) as 百円, coalesce(sum(case when price = 300 then 1 else 0 end), 0) as 三百円 from item;
explain analyze で確認してみてください。違いに驚きます。
因みに Oracle では同等の機能は decode という関数で提供されているようです。
home | prev | next |
---|