技術

SQLのCASE式とIFの比較

SQLのCASE式は強力な汎用構文です。使いこなせるに超したことはありません。

しかしながら、DBMSによってはCASE式に変わるもっと便利な書き方が存在します。

汎用SQLと実装依存SQL

SQLには、すべてのDBMSで動作する汎用構文と、DBMSオリジナルの構文があります。

後者の方は便利な書き方があることが多いのですが、当然、その特定のDBMSでしか動作しません。『SQL徹底指南書』では、これを実装依存と呼んでいます。

で、これは記憶があやふやなんですが、確か本書ではなるべく実装依存ではなく汎用構文のSQLを書いたほうが良いと言っていた気がします。

Athena(Presto)には便利なオリジナル構文がある

最近はAWSのAthenaをよく使っているのですが、AthenaはPrestoというSQLクエリエンジンを使用しています。なので、AthenaではPrestoのオリジナル構文が動作可能です。

このPrestoには便利なオリジナル構文があります。

Athenaを使っている現場は多いと思いますので、Prestoのオリジナル構文はガンガン使って良いでしょう。むしろ、使いこなすべきです。

私が今やっている案件のデータパイプラインも、汎用構文とPrestoのオリジナル構文が混ざって書かれています。最初は「なんだこの書き方は!?」と思ったですが、それはPrestoオリジナル構文でした。

で、慣れるとやはりPresto構文の方が見やすくてシンプルなコードになります。

私も新規実装を入れるときは、特に断りがないときは、Presto構文を取り入れています。

CASE式の代用が便利

CASE式は、『SQL徹底指南書』の最初の章に出てるぐらいあって、SQLには必須の構文です。

ただこのCASE式の書き方、直感的には少し分かりづらいです。CASE式には、単純CASE式と検索CASE式の2通りの書き方がありますが、よく使われるのは検索CASE式の方で、以下の様に書くことができます。

CASE
    WHEN condition THEN true_value
    [ ELSE false_value ]
END

例えばこんな感じ。(あんまり良い例ではありませんが・・・)

SELECT
    CASE
        WHEN code = 200 THEN 'OK',
        ELSE 'NG'
    END AS status

これがPrestoではこのように書けます。

SELECT
    IF(code = 200, 'OK', 'NG') AS status

参考: https://prestodb.io/docs/current/functions/conditional.html

よりプログラミング言語らしく書け、直感的でわかりやすいです。

何個も条件があるなら、CASE式でWHEN-THENを続けて書いた方が見やすいですが、条件が1つの場合は、IFを使った方がいいですね。

CASE式でnull判定するときは更に便利にかける

またこれはPrestoに限った話ではないのですが、CASEでNULL判定をするときは、COALESCEという便利な関数があります。

NULL判定は、汎用構文で書くと以下の様になります。

CASE
    WHEN column_name1 IS NULL THEN 0
    ELSE column_name1
END AS column_name1

これを、COALESCEを使えば、以下の様に書けます。

COALESCE(column_name1, 0) AS column_name1

NULL判定するケースはよくあるので、ぜひ多用していきたい書き方です。

まとめ

SQLのCASE式に変わる実装依存の書き方の紹介でした。

SQLは関数を使うと便利な書き方をできることが多いです。学習コストはかかりますが、汎用構文に執着せず、実装依存の書き方も柔軟に取り入れて行くのが良いと思います。