home prev next

PostgreSQLでのデータ集計メモ


例えば次の様なテーブルがあり、

    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

Last-modified: Tue Nov 18 12:41:14 JSP 2008
Site admin:りお

Powerd by ninjatools

ふつう このページは Another HTML-lint gatewayふつうと判断されました。