SQLで条件分岐

条件分岐という言葉を聞いた瞬間、SQLで書くことを諦めてしまう人がいる。しかし、SQLで条件分岐を書きたい時には次のどちらかのパターンを使えば良いだけである。

  • CASE 句を使う
  • UNION ALL を使う

区分によって計算方法を変えたい場合は前者を使う。

SELECT
    (CASE
        WHEN SM.貸借区分 = 'D' THEN SM.金額
        WHEN SM.貸借区分 = 'C' THEN - SM.金額
    END) AS 金額
FROM
    仕訳ヘッダ SH
    INNER JOIN 仕訳明細 SM
        ON SM.仕訳ID = SH.仕訳ID

単純な場合はこれで良いが、区分によって異なるマスタを結合しなければならない場合もある。サブクエリーを使うことでも記述は可能だが、速度が遅くなることが多く、またメンテナンス性も低くなる。その場合は、区分ごとに UNION ALL を使って分割した方が書きやすい(なお、原則としてALLのつかないUNIONの使用は極力避けるべきである。UNIONを使うと自動的にソートおよびマージが発生してしまう。ソートは比較的コストの高い処理であるし、予想しないマージが発生する恐れもある)。

SELECT
    SDH.支払日,
    SDH.支払先銀行コード,
    (CASE
        WHEN SM.貸借区分 = 'D' THEN - SM.金額
        WHEN SM.貸借区分 = 'C' THEN SM.金額
    END) AS 支払金額
FROM
    仕訳ヘッダ SH
    INNER JOIN 仕訳明細 SM
        ON SM.仕訳ID = SH.仕訳ID
    INNER JOIN 支払伝票ヘッダ SDH
        ON SDH.支払伝票ID = SH.支払伝票ID
WHERE
    SH.伝票区分 = '0A' -- 支払伝票
UNION ALL
SELECT
    TKH.支払日,
    TKH.支払先銀行コード,
    (CASE
        WHEN SM.貸借区分 = 'D' THEN - SM.金額
        WHEN SM.貸借区分 = 'C' THEN SM.金額
    END) AS 支払金額
FROM
    仕訳ヘッダ SH
    INNER JOIN 仕訳明細 SM
        ON SM.仕訳ID = SH.仕訳ID
    INNER JOIN 立替経費ヘッダ TKH
        ON SDH.立替伝票ID = SH.立替伝票ID
WHERE
    SH.伝票区分 = '0S' -- 立替経費伝票