概要
- 本記事はSQL 第2版 ゼロからはじめるデータベース操作で学んだ内容をまとめたものです。
- 前回は「第5章:複雑な問い合わせ」 で学んだ内容をまとめました:SQL 第2版 ゼロからはじめるデータベース操作 アウトプット(第8回)
- 今回は「第6章:関数、述語、CASE式」についてまとめていきます!
関数
- 関数とは、「ある値を入力すると、それに対応した値を出力する」機能のこと
- この時の入力を引数(パラメータ)と呼び、出力を戻り値と呼ぶ
算術関数
- +、-、*、/ 算術演算子を使って計算する
mysql> CREATE TABLE SampleMath
-> (m NUMERIC (10,3),
-> n INTEGER,
-> p INTEGER);
Query OK, 0 rows affected (0.08 sec)
mysql> START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (500, 0, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (-180, 0, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (NULL, NULL, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (NULL, 7, 3);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (NULL, 5, 2);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (NULL, 4, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (8, NULL, 3);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (2.27, 1, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (5.555,2, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (NULL, 1, NULL);
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO SampleMath(m, n, p) VALUES (8.76, NULL, NULL);
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> COMMIT;
Query OK, 0 rows affected (0.01 sec)
mysql> SELECT * FROM SampleMath;
+----------+------+------+
| m | n | p |
+----------+------+------+
| 500.000 | 0 | NULL |
| -180.000 | 0 | NULL |
| NULL | NULL | NULL |
| NULL | 7 | 3 |
| NULL | 5 | 2 |
| NULL | 4 | NULL |
| 8.000 | NULL | 3 |
| 2.270 | 1 | NULL |
| 5.555 | 2 | NULL |
| NULL | 1 | NULL |
| 8.760 | NULL | NULL |
+----------+------+------+
11 rows in set (0.00 sec)
- 絶対値:ABS
- 数値の符号を考えない、ゼロからの距離の大きさを表す数値
- 関数の引数がNULLの場合は、戻り値もNULLになる
mysql> SELECT m, ABS(m) AS abs_col FROM SampleMath;
+----------+---------+
| m | abs_col |
+----------+---------+
| 500.000 | 500.000 |
| -180.000 | 180.000 |
| NULL | NULL |
| NULL | NULL |
| NULL | NULL |
| NULL | NULL |
| 8.000 | 8.000 |
| 2.270 | 2.270 |
| 5.555 | 5.555 |
| NULL | NULL |
| 8.760 | 8.760 |
+----------+---------+
11 rows in set (0.01 sec)
- MOD:剰余
- 割り算の余りを求める
- SQL Serverでは、剰余演算子は
%を使う
mysql> SELECT n, p,
-> MOD(n, p) AS mod_col
-> FROM SampleMath;
+------+------+---------+
| n | p | mod_col |
+------+------+---------+
| 0 | NULL | NULL |
| 0 | NULL | NULL |
| NULL | NULL | NULL |
| 7 | 3 | 1 |
| 5 | 2 | 1 |
| 4 | NULL | NULL |
| NULL | 3 | NULL |
| 1 | NULL | NULL |
| 2 | NULL | NULL |
| 1 | NULL | NULL |
| NULL | NULL | NULL |
+------+------+---------+
11 rows in set (0.01 sec)
- ROUND: 四捨五入
ROUND(数値,丸めの桁数)- 丸めの桁数を1にすると小数点第1位で四捨五入される
- 丸めの桁数を2にすると小数点第2位で四捨五入される
mysql> SELECT m, n, ROUND(m, n) AS round_col FROM SampleMath;
+----------+------+-----------+
| m | n | round_col |
+----------+------+-----------+
| 500.000 | 0 | 500.000 |
| -180.000 | 0 | -180.000 |
| NULL | NULL | NULL |
| NULL | 7 | NULL |
| NULL | 5 | NULL |
| NULL | 4 | NULL |
| 8.000 | NULL | NULL |
| 2.270 | 1 | 2.300 |
| 5.555 | 2 | 5.560 |
| NULL | 1 | NULL |
| 8.760 | NULL | NULL |
+----------+------+-----------+
11 rows in set (0.01 sec)
文字列関数
- 文字の連結
- SQL Serverでは、+(プラス)演算子を使う
- MySQLでは、CONCAT関数を使う
mysql> SELECT str1, str2, str3, CONCAT(str1, str2, str3) AS str_concat FROM SampleStr;
+--------------------+-----------+--------+--------------------------+
| str1 | str2 | str3 | str_concat |
+--------------------+-----------+--------+--------------------------+
| あいう | えお | NULL | NULL |
| abc | def | NULL | NULL |
| 山田 | 太郎 | です | 山田太郎です |
| aaa | NULL | NULL | NULL |
| NULL | あああ | NULL | NULL |
| @!#$% | NULL | NULL | NULL |
| ABC | NULL | NULL | NULL |
| aBC | NULL | NULL | NULL |
| abc太郎 | abc | ABC | abc太郎abcABC |
| abcdefabc | abc | ABC | abcdefabcabcABC |
| ミックマック | ッ | っ | ミックマックッっ |
+--------------------+-----------+--------+--------------------------+
11 rows in set (0.01 sec)
-
LENGTH: 文字列の長さ
- 文字列の長さを求める
- SQL Serverでは、LEN関数を使う
- MySQLでは、LENGTH関数を使う
- 文字列の長さは、バイト数で返される
- バイト数:1文字あたり1バイトの文字列は1バイト、2バイトの文字列は2バイト
-
あいう(全角3文字)は9バイト
-
abc(半角3文字)は3バイト
-
山田(全角2文字)は6バイト
mysql> SELECT str1, LENGTH(str1) AS len_str FROM SampleStr;
+--------------------+---------+
| str1 | len_str |
+--------------------+---------+
| あいう | 9 |
| abc | 3 |
| 山田 | 6 |
| aaa | 3 |
| NULL | NULL |
| @!#$% | 5 |
| ABC | 3 |
| aBC | 3 |
| abc太郎 | 9 |
| abcdefabc | 9 |
| ミックマック | 18 |
+--------------------+---------+
11 rows in set (0.00 sec)
- LOWER: 小文字化
- アルファベットを小文字に変換する
mysql> SELECT str1, LOWER(str1) AS low_str FROM SampleStr;
+--------------------+--------------------+
| str1 | low_str |
+--------------------+--------------------+
| あいう | あいう |
| abc | abc |
| 山田 | 山田 |
| aaa | aaa |
| NULL | NULL |
| @!#$% | @!#$% |
| ABC | abc |
| aBC | abc |
| abc太郎 | abc太郎 |
| abcdefabc | abcdefabc |
| ミックマック | ミックマック |
+--------------------+--------------------+
11 rows in set (0.01 sec)
- UPPER: 大文字化
- アルファベットを大文字に変換する
mysql> SELECT str1, UPPER(str1) AS up_str FROM SampleStr WHERE str1 IN ('ABC', 'aBC', 'abc');
+------+--------+
| str1 | up_str |
+------+--------+
| abc | ABC |
| ABC | ABC |
| aBC | ABC |
+------+--------+
3 rows in set (0.01 sec)
- REPLACE: 文字列の置換
- 文字列の一部を別の文字列に置き換える
REPLACE(対象文字列, 検索文字列, 置換文字列)
mysql> SELECT str1, str2, str3, REPLACE(str1, str2, str3) AS rep_str FROM SampleStr;
+--------------------+-----------+--------+--------------------+
| str1 | str2 | str3 | rep_str |
+--------------------+-----------+--------+--------------------+
| あいう | えお | NULL | NULL |
| abc | def | NULL | NULL |
| 山田 | 太郎 | です | 山田 |
| aaa | NULL | NULL | NULL |
| NULL | あああ | NULL | NULL |
| @!#$% | NULL | NULL | NULL |
| ABC | NULL | NULL | NULL |
| aBC | NULL | NULL | NULL |
| abc太郎 | abc | ABC | ABC太郎 |
| abcdefabc | abc | ABC | ABCdefABC |
| ミックマック | ッ | っ | ミっクマっク |
+--------------------+-----------+--------+--------------------+
11 rows in set (0.01 sec)
- SUBSTRING: 文字列の切り出し
- 文字列の一部を切り出す
SUBSTRING(対象文字列, 開始位置, 長さ)- 開始位置は1から始まる
-- 文字列の左から3文字目から2文字を切り出す
mysql> SELECT str1, SUBSTRING(str1 FROM 3 FOR 2) AS sub_str FROM SampleStr;
+--------------------+---------+
| str1 | sub_str |
+--------------------+---------+
| あいう | う |
| abc | c |
| 山田 | |
| aaa | a |
| NULL | NULL |
| @!#$% | #$ |
| ABC | C |
| aBC | C |
| abc太郎 | c太 |
| abcdefabc | cd |
| ミックマック | クマ |
+--------------------+---------+
11 rows in set (0.00 sec)
日付関数
- CURRENT_DATE: 現在の日付
- 現在の日付を取得する
- SQL Serverでは、GETDATE関数(
SELECT GETDATE();)を使う
mysql> SELECT CURRENT_DATE();
+----------------+
| CURRENT_DATE() |
+----------------+
| 2025-06-11 |
+----------------+
1 row in set (0.01 sec)
- CURRENT_TIME: 現在の時刻
- 現在の時刻を取得する
- SQL Serverでは、CURRENT_TIME関数(
SELECT CAST(CURRENT_TIMESTAMP AS time) AS CUR_TIME;)を使う
mysql> SELECT CURRENT_TIME();
+----------------+
| CURRENT_TIME() |
+----------------+
| 04:52:34 |
+----------------+
1 row in set (0.00 sec)
- CURRENT_TIMESTAMP: 現在の日付と時刻
- 現在の日付と時刻を取得する
- SQL Serverも、CURRENT_TIMESTAMP関数(
SELECT CURRENT_TIMESTAMP;)を使う
mysql> SELECT CURRENT_TIMESTAMP;
+---------------------+
| CURRENT_TIMESTAMP |
+---------------------+
| 2025-06-11 04:53:29 |
+---------------------+
1 row in set (0.00 sec)
- EXTRACT: 日付の一部を抽出
- 日付から年、月、日などの一部を抽出する
- SQL Serverでは、DATEPART関数を使う
EXTRACT(部分, 日付)
mysql> SELECT CURRENT_DATE(), EXTRACT(YEAR FROM CURRENT_TIMESTAMP()) AS year,
-> EXTRACT(MONTH FROM CURRENT_TIMESTAMP()) AS month,
-> EXTRACT(DAY FROM CURRENT_TIMESTAMP()) AS day,
-> EXTRACT(HOUR FROM CURRENT_TIMESTAMP) AS hour,
-> EXTRACT(MINUTE FROM CURRENT_TIMESTAMP) AS minute,
-> EXTRACT(SECOND FROM CURRENT_TIMESTAMP) AS second;
+----------------+------+-------+------+------+--------+--------+
| CURRENT_DATE() | year | month | day | hour | minute | second |
+----------------+------+-------+------+------+--------+--------+
| 2025-06-11 | 2025 | 6 | 11 | 4 | 58 | 6 |
+----------------+------+-------+------+------+--------+--------+
1 row in set (0.01 sec)
-- SQL Serverでの例
SELECT CURRENT_TIMESTAMP,
DATEPART(YEAR, CURRENT_TIMESTAMP) AS year,
DATEPART(MONTH, CURRENT_TIMESTAMP) AS month,
DATEPART(DAY, CURRENT_TIMESTAMP) AS day,
DATEPART(HOUR, CURRENT_TIMESTAMP) AS hour,
DATEPART(MINUTE, CURRENT_TIMESTAMP) AS minute,
DATEPART(SECOND, CURRENT_TIMESTAMP) AS second;
変換関数
-
CAST(値 AS 型)- 値を指定した型に変換する
- SQL Serverでも同様に、
CAST(値 AS 型)を使う
mysql> SELECT CAST('0001' AS SIGNED INTEGER) AS int_col;
+---------+
| int_col |
+---------+
| 1 |
+---------+
1 row in set (0.00 sec)
mysql> SELECT CAST('2025-06-11' AS DATE) AS date_col;
+------------+
| date_col |
+------------+
| 2025-06-11 |
+------------+
1 row in set (0.00 sec)
- COALESCE: NULL値の置換
- 引数の中で最初にNULLでない値を返す
- SQL Serverでも同様に、
COALESCE(値1, 値2, ...)を使う
mysql> SELECT COALESCE(NULL, 1) AS col_1, COALESCE(NULL, 'test', NULL) AS col_2, COALESCE(NULL, NULL, '2025-06-11');
+-------+-------+------------------------------------+
| col_1 | col_2 | COALESCE(NULL, NULL, '2025-06-11') |
+-------+-------+------------------------------------+
| 1 | test | 2025-06-11 |
+-------+-------+------------------------------------+
1 row in set (0.01 sec)
mysql> SELECT COALESCE(str2, 'NULL!!') FROM SampleStr;
+--------------------------+
| COALESCE(str2, 'NULL!!') |
+--------------------------+
| えお |
| def |
| 太郎 |
| NULL!! |
| あああ |
| NULL!! |
| NULL!! |
| NULL!! |
| abc |
| abc |
| ッ |
+--------------------------+
11 rows in set (0.00 sec)
述語
- 述語とは、戻り値が真偽値(TRUE/FALSE)になる関数のこと
-
LIKE,BETWEEN,IS NULL,IS NOT NULL,IN,EXISTSなどがある
-
LIKE述語
- 文字列の部分一致を検索する
- 前方一致:
LIKE 'abc%' - 後方一致:
LIKE '%abc' - 中間一致:
LIKE '%abc%'
- 前方一致:
- 文字列そのものを「=」で指定するのではなく、文字列の中に含まれる規則に基づいて検索することを「パターンマッチング」と呼ぶ
- パターンマッチングでは、ワイルドカードを使うことができる
-
%:任意の文字列(0文字以上) -
_:任意の1文字
-
CREATE TABLE SampleLike
( strcol VARCHAR(6) NOT NULL,
PRIMARY KEY (strcol));
START TRANSACTION;
INSERT INTO SampleLike (strcol) VALUES ('abcddd');
INSERT INTO SampleLike (strcol) VALUES ('dddabc');
INSERT INTO SampleLike (strcol) VALUES ('abdddc');
INSERT INTO SampleLike (strcol) VALUES ('abcdd');
INSERT INTO SampleLike (strcol) VALUES ('ddabc');
INSERT INTO SampleLike (strcol) VALUES ('abddc');
COMMIT;
mysql> SELECT * FROM SampleLike WHERE strcol LIKE 'ddd%';
+--------+
| strcol |
+--------+
| dddabc |
+--------+
1 row in set (0.00 sec)
mysql> SELECT * FROM SampleLike WHERE strcol LIKE '%ddd%';
+--------+
| strcol |
+--------+
| abcddd |
| abdddc |
| dddabc |
+--------+
3 rows in set (0.00 sec)
mysql> SELECT * FROM SampleLike WHERE strcol LIKE '%ddd';
+--------+
| strcol |
+--------+
| abcddd |
+--------+
1 row in set (0.00 sec)
mysql> SELECT * FROM SampleLike WHERE strcol LIKE 'abc__';
+--------+
| strcol |
+--------+
| abcdd |
+--------+
1 row in set (0.01 sec)
mysql> SELECT * FROM SampleLike WHERE strcol LIKE 'abc___';
+--------+
| strcol |
+--------+
| abcddd |
+--------+
1 row in set (0.00 sec)
BETWEEN述語
- 範囲検索を行う
BETWEEN 開始値 AND 終了値
-- BETWEEN述語は、開始値と終了値を含む
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin WHERE hanbai_tanka BETWEEN 100 AND 1000;
+--------------------+--------------+
| shohin_mei | hanbai_tanka |
+--------------------+--------------+
| Tシャツ | 1000 |
| 穴あけパンチ | 500 |
| フォーク | 500 |
| おろしがね | 880 |
| ボールペン | 100 |
+--------------------+--------------+
5 rows in set (0.00 sec)
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin WHERE hanbai_tanka > 100 AND hanbai_tanka < 1000;
+--------------------+--------------+
| shohin_mei | hanbai_tanka |
+--------------------+--------------+
| 穴あけパンチ | 500 |
| フォーク | 500 |
| おろしがね | 880 |
+--------------------+--------------+
3 rows in set (0.00 sec)
IS NULL, IS NOT NULL述語
- NULL値の判定を行う
-
IS NULL: NULL値であるかどうかを判定する -
IS NOT NULL: NULL値でないかどうかを判定する
-
mysql> SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka IS NULL;
+-----------------+--------------+
| shohin_mei | shiire_tanka |
+-----------------+--------------+
| フォーク | NULL |
| ボールペン | NULL |
+-----------------+--------------+
2 rows in set (0.00 sec)
mysql> SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka IS NOT NULL;
+-----------------------+--------------+
| shohin_mei | shiire_tanka |
+-----------------------+--------------+
| Tシャツ | 500 |
| 穴あけパンチ | 320 |
| カッターシャツ | 2800 |
| 包丁 | 2800 |
| 圧力鍋 | 5000 |
| おろしがね | 790 |
+-----------------------+--------------+
6 rows in set (0.00 sec)
IN述語
- 複数の値の中から一致する値を検索する
IN (値1, 値2, ...)- OR述語の代わりに使うことができる
- NULLを選択することはできない
- NULLを含む場合は、IS NULL述語を使う必要がある
mysql> SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka IN (320, 500, 5000);
+--------------------+--------------+
| shohin_mei | shiire_tanka |
+--------------------+--------------+
| Tシャツ | 500 |
| 穴あけパンチ | 320 |
| 圧力鍋 | 5000 |
+--------------------+--------------+
3 rows in set (0.00 sec)
mysql> SELECT shohin_mei, shiire_tanka FROM Shohin WHERE shiire_tanka NOT IN (320, 500, 5000);
+-----------------------+--------------+
| shohin_mei | shiire_tanka |
+-----------------------+--------------+
| カッターシャツ | 2800 |
| 包丁 | 2800 |
| おろしがね | 790 |
+-----------------------+--------------+
3 rows in set (0.00 sec)
IN述語の応用
- IN述語は、サブクエリと組み合わせて使うことができる
- サブクエリの結果をIN述語の値として使用する
CREATE TABLE TenpoShohin
(tenpo_id CHAR(4) NOT NULL,
tenpo_mei VARCHAR(200) NOT NULL,
shohin_id CHAR(4) NOT NULL,
suryo INTEGER NOT NULL,
PRIMARY KEY (tenpo_id, shohin_id));
START TRANSACTION;
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000A', '東京', '0001', 30);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000A', '東京', '0002', 50);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000A', '東京', '0003', 15);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000B', '名古屋', '0002', 30);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000B', '名古屋', '0003', 120);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000B', '名古屋', '0004', 20);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000B', '名古屋', '0006', 10);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000B', '名古屋', '0007', 40);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000C', '大阪', '0003', 20);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000C', '大阪', '0004', 50);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000C', '大阪', '0006', 90);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000C', '大阪', '0007', 70);
INSERT INTO TenpoShohin (tenpo_id, tenpo_mei, shohin_id, suryo) VALUES ('000D', '福岡', '0001', 100);
COMMIT;
-- 大阪店(tenpo_id = '000C')で取り扱っている商品の販売単価を求める
mysql> SELECT shohin_id FROM TenpoShohin WHERE tenpo_id = '000C';
+-----------+
| shohin_id |
+-----------+
| 0003 |
| 0004 |
| 0006 |
| 0007 |
+-----------+
4 rows in set (0.00 sec)
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin WHERE shohin_id IN ( SELECT shohin_id FROM TenpoShohin WHERE tenpo_id = '000C');
+-----------------------+--------------+
| shohin_mei | hanbai_tanka |
+-----------------------+--------------+
| カッターシャツ | 4000 |
| 包丁 | 3000 |
| フォーク | 500 |
| おろしがね | 880 |
+-----------------------+--------------+
4 rows in set (0.00 sec)
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin WHERE shohin_id NOT IN ( SELECT shohin_id FROM TenpoShohin WHERE tenpo_id = '000A');
+-----------------+--------------+
| shohin_mei | hanbai_tanka |
+-----------------+--------------+
| 包丁 | 3000 |
| 圧力鍋 | 6800 |
| フォーク | 500 |
| おろしがね | 880 |
| ボールペン | 100 |
+-----------------+--------------+
5 rows in set (0.00 sec)
EXISTS述語
- EXISTS術後の役割:「ある条件に合致するレコードの存在有無を調べる」こと
- 存在すればTRUE、存在しなければFALSEを返す
- EXISTSの引数は常に相関サブクエリでなければならない
- 相関サブクエリとは、外側のクエリの値を参照するサブクエリのこと
- EXISTSの引数のサブクエリは常に**SELECT ***を指定する
-- 大阪店(tenpo_id = '000C')で取り扱っている商品の販売単価を求める
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin S1 WHERE EXISTS (SELECT * FROM TenpoShohin TS WHERE TS.tenpo_id = '000C' AND TS.shohin_id = S1.shohin_id);
+-----------------------+--------------+
| shohin_mei | hanbai_tanka |
+-----------------------+--------------+
| カッターシャツ | 4000 |
| 包丁 | 3000 |
| フォーク | 500 |
| おろしがね | 880 |
+-----------------------+--------------+
4 rows in set (0.00 sec)
-- 東京店(tenpo_id = '000A')に置いてある商品以外の販売単価を求める
mysql> SELECT shohin_mei, hanbai_tanka FROM Shohin S1 WHERE NOT EXISTS (SELECT * FROM TenpoShohin TS WHERE TS.tenpo_id = '000A' AND TS.shohin_id = S1.shohin_id);
+-----------------+--------------+
| shohin_mei | hanbai_tanka |
+-----------------+--------------+
| 包丁 | 3000 |
| 圧力鍋 | 6800 |
| フォーク | 500 |
| おろしがね | 880 |
| ボールペン | 100 |
+-----------------+--------------+
5 rows in set (0.00 sec)
CASE式
- CASE式は、条件分岐を行うための式
- 単純CASE式と検索CASE式の2種類がある
- 検索CASE式は、複数の条件を指定して、それぞれの条件に応じた値を返すことができる
CASE WHEN 条件1 THEN 値1 WHEN 条件2 THEN 値2 ... ELSE デフォルト値 END
- 行列変換:
- 行列変換とは、行と列を入れ替えること
- CASE式を使って、行列変換を行うことができる
-- CASE式で商品分類にA〜Cの文字列を割り当てる
mysql> SELECT
-> shohin_mei,
-> CASE
-> WHEN shohin_bunrui = '衣服' THEN CONCAT('A: ', shohin_bunrui)
-> WHEN shohin_bunrui = '事務用品' THEN CONCAT('B: ', shohin_bunrui)
-> WHEN shohin_bunrui = 'キッチン用品' THEN CONCAT('C: ', shohin_bunrui)
-> ELSE NULL
-> END AS abc_shohin_bunrui
-> FROM Shohin;
+-----------------------+-------------------+
| shohin_mei | abc_shohin_bunrui |
+-----------------------+-------------------+
| Tシャツ | A: 衣服 |
| 穴あけパンチ | B: 事務用品 |
| カッターシャツ | A: 衣服 |
| 包丁 | C: キッチン用品 |
| 圧力鍋 | C: キッチン用品 |
| フォーク | C: キッチン用品 |
| おろしがね | C: キッチン用品 |
| ボールペン | B: 事務用品 |
+-----------------------+-------------------+
8 rows in set (0.01 sec)
-- 行列変換、商品分類ごとに販売単価を合計した結果を行列変換する
mysql> SELECT
-> SUM(CASE WHEN shohin_bunrui = '衣服' THEN hanbai_tanka ELSE 0 END) AS sum_tanka_ifuku,
-> SUM(CASE WHEN shohin_bunrui = 'キッチン用品' THEN hanbai_tanka ELSE 0 END) AS sum_tanka_kitchen,
-> SUM(CASE WHEN shohin_bunrui = '事務用品' THEN hanbai_tanka ELSE 0 END) AS sum_tanka_office
-> FROM Shohin;
+-----------------+-------------------+------------------+
| sum_tanka_ifuku | sum_tanka_kitchen | sum_tanka_office |
+-----------------+-------------------+------------------+
| 5000 | 11180 | 600 |
+-----------------+-------------------+------------------+
1 row in set (0.00 sec)
練習問題を解いてみる
- 6.1 - 6.2を解いてみた内容を掲載
6.1
- クエリの実行
mysql> CREATE VIEW ViewRenshu5_1 AS SELECT shohin_mei, hanbai_tanka, torokubi FROM Shohin WHERE hanbai_tanka >= 1000 AND torokubi = '2009-09-20';
Query OK, 0 rows affected (0.02 sec)
mysql> SELECT * FROM ViewRenshu5_1;
+------------+--------------+------------+
| shohin_mei | hanbai_tanka | torokubi |
+------------+--------------+------------+
| Tシャツ | 1000 | 2009-09-20 |
| 包丁 | 3000 | 2009-09-20 |
+------------+--------------+------------+
2 rows in set (0.00 sec)
6-2
- 行列変換
-- 低額商品(販売単価が1000以下)、中額商品(販売単価が1000以上3000以下)、高額商品(販売単価が3001以上)の商品数を求める
mysql> SELECT SUM(CASE WHEN hanbai_tanka <= 1000 THEN 1 ELSE 0 END) AS low_price,
-> SUM(CASE WHEN hanbai_tanka BETWEEN 1001 AND 3000 THEN 1 ELSE 0 END) AS mid_price,
-> SUM(CASE WHEN hanbai_tanka >= 3001 THEN 1 ELSE 0 END) AS high_price FROM Shohin;
+-----------+-----------+------------+
| low_price | mid_price | high_price |
+-----------+-----------+------------+
| 5 | 1 | 2 |
+-----------+-----------+------------+
1 row in set (0.01 sec)
まとめ
- 本記事では「第6章:関数、述語、CASE式」 についてまとめました!
- 次回は「第7章:集合演算」 についてまとめていきます!