7
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have 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
9
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
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?