それ集約関数とCASE式(もしくはただの計算式)で

SQLServer2005からの新機能「Pivot句」 - 山本大@クロノスの日記

Pivot句なんてものがあったのか・・・
ただ、例にしている「テーブル行の横展開」だけど、「ゴリゴリ組む」必要なんてないし、Pivot句を使うよりコードとしては短くなるよ。
こんな感じ*1

SELECT
    '男女比' as title
  , sum(CASE is_male WHEN 0 THEN 1 END) as female
  , sum(CASE is_male WHEN 1 THEN 1 END) as male
FROM
    Users

SQL Server 2000でしか試してないけど、bitって

, sum(CASE WHEN NOT is_male THEN 1 END) as female
, sum(CASE WEHEN is_male THEN 1 END) as male

って書けないのが中途半端だよなぁ。
こういうところは真偽値っぽくないのに、sum(is_male)とかできないところは数値っぽくない。いったいどっちなんだよ、と。
上のようにかけたら一番わかりやすいと思うんだけど。


ほかにも、CASE式を使わずに

SELECT
    '男女比' as title
  , sum(-(is_male - 1)) as female
  , sum(cast(is_male as int)) as male
FROM
    Users

とやってもいい。人によってはこっちのほうがわかりやすいかも。
まぁどちらの方法をとったとしても、Pivot句を使った方法

SELECT
    '男女比' as title
  , [0] as female
  , [1] as male
FROM
    (SELECT id, is_male FROM Users) as u
PIVOT
(
    count(id)
    FOR u.is_male IN ([0], [1])
) AS PivotTable

よりもわかりやすいし短い*2


ちなみに、is_maleとしたのにはちょっとした理由があって、性別って本当に真偽値でいいの?ってのをはっきりさせたかったというのがある。
is_maleは「男性かどうか」をかなり直接的に表してるけど、男性じゃないってことは女性と決まるの?と。
ISOでは0が不明、1が男性、2が女性、9が適用不能と定義されているんだから、それに合わせとくのが吉かな、と思うんだけどどうなんだろう。
ま、これは本題とは関係ない些末な事柄。

*1:テーブル定義は自分の好みに合わせて微妙に変更

*2:と言うより、このクエリ読みにくいよ・・・