LoginSignup
14
2

More than 1 year has passed since last update.

【SQL】これ以上の値上げは勘弁してください 。CASE式で正しく値上げする

Last updated at Posted at 2022-11-14

はじめに

株式会社YUZURIHAの馬場です

昨日、何気なく買ったピノが1個175円 ぐらいしたので値段間違ってる?と疑ってしまったので記事書きました

まずは、アイスクリームテーブルを用意

CREATE TABLE ice_cream
(
  id INT NOT NULL,
  name VARCHAR(100) NOT NULL,
  type VARCHAR(32) NOT NULL,
  price INT,
  delivery_date DATE,
  PRIMARY KEY (id)
);

INSERT INTO ice_cream VALUES (1, 'BLUE SEAL' ,'ラクトアイス', 300, '2022-09-20');
INSERT INTO ice_cream VALUES (2, 'スーパーカップ' ,'ラクトアイス', 120, '202-08-01');
INSERT INTO ice_cream VALUES (3, '北極アイスキャンデー' ,'ラクトアイス', 100, '2022-09-20');
INSERT INTO ice_cream VALUES (4, 'ガリガリ君' ,'氷菓', 60, '2022-08-30');
INSERT INTO ice_cream VALUES (5, 'PARM(パルム)' ,'アイスクリーム', 150, '2022-09-20');
INSERT INTO ice_cream VALUES (6, '雪見だいふく' ,'アイスミルク', 120, '2022-09-20');
INSERT INTO ice_cream VALUES (7, 'sacre(サクレ)' ,'氷菓', 90, '2022-08-01');

こんな感じですねー(データはもちろん仮です)

postgres=# select * from ice_cream;
 id |      name      |      type      | price | delivery_date
----+----------------+----------------+-------+---------------
  1 | BLUE SEAL     | ラクトアイス      |   300 | 2022-09-20
  2 | スーパーカップ    | ラクトアイス     |   120 | 2022-08-01
  3 | 北極アイスキャンデー| ラクトアイス     |   100 | 2022-09-20
  4 | ガリガリ君       | 氷菓            |    60 | 2022-08-30
  5 | PARM(パルム)   | アイスクリーム      |   150 | 2022-09-20
  6 | 雪見だいふく     | アイスミルク       |   120 | 2022-09-20
  7 | sacre(サクレ)   | 氷菓            |    90 | 2022-08-01
(7 rows)

さあ、値上げをしよう

ある日、

・100円以上、140円未満の商品は20%の値上げ
・140円以上の商品は10%の値上げ
が決定したとします

てことは、毎週買ってるスーパーカップが144円に😱

そして、泣く泣くデータを更新をすることに。。。

はいはい、簡単ですよ。単純なUPDATE文ですよね

最初に

update ice_cream set price = price * 1.2 where 100 <= price and price < 150;

を実行して、ほんで

update ice_cream set price = price * 1.1 where price >= 150;

はい。これで完成と。

(更新後)
 id |      name      |      type      | price | delivery_date
----+----------------+----------------+-------+---------------
  4 | ガリガリ君        | 氷菓           |    60 | 2022-08-30
  7 | sacre(サクレ)    | 氷菓           |    90 | 2022-08-01
  3 | 北極アイスキャンデー| ラクトアイス      |   120 | 2022-09-20    
  1 | BLUE SEAL      | ラクトアイス     |   330 | 2022-09-20
  5 | PARM(パルム)    | アイスクリーム     |   165 | 2022-09-20
  2 | スーパーカップ    | ラクトアイス       |   158 | 2022-08-01
  6 | 雪見だいふく      | アイスミルク      |   158 | 2022-09-20

🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱🙀😱

スーパーカップ 158円 !?!?
スーパーカップと、雪見だいふくが2度値上げされている
大好きなスーパーカップ チョコチップ味はもう上級国民御用達アイスに成り上がりました

先ほどのSQLでは、
条件1と、条件2 の2つに分けてUPDATEを行なっていることが良くないです。
条件1の値上げの後に、条件2にも当てはまれば2度更新されるのも当然です

CASE式で正しく値上げする

ここで使用するのがCASE式です。UPDATE内で1度で条件分岐で済みます。
正しくは以下のSQLですね

update ice_cream
    set price = 
        case when 100 <= price and price < 140 then price * 1.2
             when price >= 140 then price * 1.1 
             else price
        end;

以下が、正しく値上げされたもの

 id |      name      |      type      | price | delivery_date
----+----------------+----------------+-------+---------------
  1 | BLUE SEAL      | ラクトアイス      |   330 | 2022-09-20
  2 | スーパーカップ    | ラクトアイス        |   144 | 2022-08-01
  3 | 北極アイスキャンデー| ラクトアイス       |   120 | 2022-09-20
  4 | ガリガリ君       | 氷菓             |    60 | 2022-08-30
  5 | PARM(パルム)   | アイスクリーム      |   165 | 2022-09-20
  6 | 雪見だいふく      | アイスミルク      |   144 | 2022-09-20
  7 | sacre(サクレ)   | 氷菓            |    90 | 2022-08-01

else priceが無いと、値段にはNULLが出力されてしまうのでここでは必須になります。

最後に

値上げなんてやめて、閉店セールにでもしましょうか

update ice_cream set price = price * 0.5;
 id |      name      |      type      | price | delivery_date
----+----------------+----------------+-------+---------------
  1 | BLUE SEAL      | ラクトアイス     |   150 | 2022-09-20
  2 | スーパーカップ    | ラクトアイス       |    60 | 2022-08-01
  3 | 北極アイスキャンデー | ラクトアイス      |    50 | 2022-09-20
  4 | ガリガリ君        | 氷菓           |    30 | 2022-08-30
  5 | PARM(パルム)    | アイスクリーム     |    75 | 2022-09-20
  6 | 雪見だいふく     | アイスミルク       |    60 | 2022-09-20
  7 | sacre(サクレ)   | 氷菓            |    45 | 2022-08-01
14
2
0

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
14
2