見出し画像

【SQL】 COUNT関数をSELECT句のCASE式条件分岐で使ったらハマった話

関数まみれの重たいエクセルでのデータ分析して消耗している皆様こんばんわ!!!
金山雄星です。

今日はRedashのダッシュボード作成でSQLを書いていたときに少しハマってしまった時の話。

SELECT pref_name,

SUM(CASE WHEN sex='1' THEN population ELSE 0 END)AS cnt_m,
SUM(CASE WHEN sex='2' THEN population ELSE 0 END)AS cnt_f
FROM PopTbl2

GROUP BY pref_name;

上のコードのようにSELECT句でCASE式を使って、条件分岐して集計しようとしてました。
(ちなみに上記のコードは、愛読書「達人に学ぶSQL徹底指南書」より引用。)
もちろんアフィリエイトリンクなんで、気になった方は検索などせずに下のバナーから飛んでくださいね!笑


普段、SUM関数で行うときは上のコードの丸パクリで上手くいってたのですが、今回、COUNT関数を使うと沼にハマりました。

❌間違ったコード

SELECT ym,

COUNT(CASE WHEN sex='1' THEN id ELSE 0 END)AS cnt_m,
COUNT(CASE WHEN sex='2' THEN id ELSE 0 END)AS cnt_f

FROM orders

GROUP BY ym;

いつものSUMでやってた要領でCOUNTすると
実行エラーにはならいものの数字が合わない、、

⭕️正解のコード

SELECT ym,

COUNT(CASE WHEN sex='1' THEN id ELSE NULL END)AS cnt_m,
COUNT(CASE WHEN sex='2' THEN id ELSE NULL END)AS cnt_f

FROM orders

GROUP BY ym;

どこを変えたか分かりました??

ELSE 0 → ELSE NULLと修正したんです。

理由を説明すると
CASE式のやっていることはラベルの読み替えでしかないので、
イメージとしてはWHENの条件にヒットしなかったカラムは、ELSE 0なら0に書き替えられて集計計算されている。
SUMの場合は0を足した値が正になるが、
COUNTの場合は0になったレコードも数えられてしまって、CASE式の条件分岐が機能していないように見えていたという訳。

ELSE NULLとすることで解決。

結論

・CASE式のやっていることはラベルの読み替えでしかない
・集約関数をSELECT句でCASE式を用いた条件分岐で使うときは
SUMの時は ELSE 0
COUNTの時は ”ELSE NULL”
で上手くいく!

BIツールが入ってるとドライブがCSVまみれにならなくて最高ですね。


役に立ったという方はいいねよろしくお願いします!
Twitterも見ていってくださいね!
https://twitter.com/YuseiKanayama

金山雄星


P.S.
noteでSQLのソースコードをもうちょっとキレイに書く方法はないでしょうか、、

この記事が気に入ったらサポートをしてみませんか?