Database JUNKY

MySQL,MariaDBを中心としたブログです

CASEと共通表式を応用した集計SQL

本来は、SQLでやるんじゃなくて、テーブルの設計とかプログラミングの過程で設定するのがベストだと思うのだけれども、急な調査でたとえば、「現在登録されているユーザーで各キャリアの分布をすぐとってほしい」なんて依頼があったらこんな形でSQLを発行すれば期待したデータが出せるよっていう例です。下記例は、MySQLで試したけど、OracleでもDB2でも同様に(いや、もっとスマートに)できるはずなのでお試しあれ

[sql]

create table mail_table ( mail  varchar(100) );

insert into mail_table values ('abcdefgrhtyghjiaaaaaaa@ezweb.ne.jp'); insert into mail_table values ('abcdefgrhtyghjiaaaaaaa@docomo.ne.jp'); insert into mail_table values ('abcdefgrhtyghjiaaaaaaa@isoftbank.jp'); insert into mail_table values ('djaslkjdlakjdklsajdlkasdj@isoftbank.jp'); insert into mail_table values ('abcdefgrhcdededtyghjiaaaaaaa@docomo.ne.jp'); insert into mail_table values ('abcdefgrhtyghjfrsfsrfsreiaaaaaaa@ezweb.ne.jp'); insert into mail_table values ('djaslkjdlakjdklsajdlkasdj@softbank.ne.jp');

select s1.carrier , count(s1.carrier) as cnt from ( select case when LOCATE('docomo.ne.jp', usr.mail) > 0 then 'docomo' when LOCATE('ezweb.ne.jp', usr.mail) > 0 then 'au' when LOCATE('softbank.ne.jp', usr.mail) > 0 then 'softbank' when LOCATE('vodafone.ne.jp', usr.mail) > 0 then 'softbank' when LOCATE('disney.ne.jp', usr.mail) > 0 then 'softbank' when LOCATE('i.softbank.jp', usr.mail) > 0 then 'softbank_iphone' else 'PC' end as carrier

from mail_table usr )  as s1 group by s1.carrier;

+----------+-----+ | carrier  | cnt | +----------+-----+ | au       |   2 | | docomo   |   2 | | PC       |   2 | | softbank |   1 | +----------+-----+ [/sql]