LoginSignup
7
7

More than 1 year has passed since last update.

SQL CASEを使って条件分岐させてみた

Last updated at Posted at 2021-08-24

CASEで条件分岐させてDBから値を取得しようとした時に書き方がわからなくて
少し手こずったのでおさらい:writing_hand_tone1:
ちなみに元々のクエリ文はWHERE句のみ(ANDやORを使って)で
20行以上あったのが8行にまとまりました!
CASEすごい!便利:clap_tone1:

仕様:選択項目がすべての場合は全件取得、値が選択された場合はその値だけを取得する
DB:MariaDB

まず、CASE式とは

プログラム言語にあるif文のような条件文をSQLでも書くことができる
それがCASE式です。
CASE式とはの説明がわかりやすい記事、参考にしたのはここ→https://qiita.com/sfp_waterwalker/items/acc7f95f6ab5aa5412f3

WHERE句でCASEを使う

いろんなところにCASE式が書けるみたいですが私はWHERE句に書きました!

構文 CASE WHEN [条件] THEN [条件を満たしたら表示する内容] ELSE [条件を満たしていなかったら表示する内容] END

SELECT * FROM table
WHERE
 CASE WHEN :value1<>'全て' THEN :value1=value1 ELSE 1=1 END
   AND
 CASE WHEN :value2<>'全て' THEN :value2=value2 ELSE 1=1 END
   AND
 CASE WHEN :date IS NOT NULL THEN STR_TO_DATE(date, '%Y%m%d') >= STR_TO_DATE(:date, '%Y%m%d') ELSE 1=1 END
   AND
 CASE WHEN :enddate IS NOT NULL THEN STR_TO_DATE(enddate, '%Y%m%d') >= STR_TO_DATE(:enddate, '%Y%m%d') ELSE 1=1 END"

条件をいくつも書きたい場合、ANDを使って書ける

※ELSE 1=1 は全件取得

書き方でわからなかったところ

CASE WHEN [条件] THEN [条件を満たしたら表示する内容] ELSE [条件を満たしていなかったら表示する内容] END

CASEの構文はわかったがつなげて何個も条件分岐を書きたかったので、最初は CASE〜ENDの中に全部条件を書いてしまった

失敗例1 CASE  WHEN :value1<>'全て' THEN :value1=value1  WHEN :value2<>'全て' THEN :value2=value2  WHEN :date IS NOT NULL THEN STR_TO_DATE(date, '%Y%m%d') >= STR_TO_DATE(:date, '%Y%m%d')  WHEN :enddate IS NOT NULL THEN STR_TO_DATE(enddate, '%Y%m%d') >= STR_TO_DATE(:enddate, '%Y%m%d')   ELSE 1=1 END

この状態だと、どれか条件にマッチした場合他の条件文を通らなくなってしまった

失敗例2 CASE  WHEN :value1<>'全て' THEN :value1=value1 ELSE 1=1  WHEN :value2<>'全て' THEN :value2=value2 ELSE 1=1  WHEN :date IS NOT NULL THEN STR_TO_DATE(date, '%Y%m%d') >= STR_TO_DATE(:date, '%Y%m%d') ELSE 1=1  WHEN :enddate IS NOT NULL THEN STR_TO_DATE(enddate, '%Y%m%d') >= STR_TO_DATE(:enddate, '%Y%m%d') ELSE 1=1 END

1行ずつWHEN [条件] THEN [条件を満たしたら表示する内容]ELSE [条件を満たしていなかったら表示する内容]
で書いてみたが構文エラー、下記のようにCASE〜ENDで囲われていないからかな?と思い‥

CASE WHEN [条件] THEN [条件を満たしたら表示する内容] ELSE [条件を満たしていなかったら表示する内容] END

私的な解釈、考え方

CASE ~ END は if文でゆう if(){ }←ブロック(波括弧)に置き換えるとわかりやすい!

CASE WHEN :value1<>'全て' THEN :value1=value1 ELSE 1=1 END

↑この一文は↓のイメージ:bulb:(※このif文はあくまでイメージです。)

if(value1<>'全て'){
  :value1=value1
}else{
  1=1 
}
7
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
7