0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SQL 第2版 ゼロからはじめるデータベース操作 アウトプット(第9回)

Posted at

概要

関数

  • 関数とは、「ある値を入力すると、それに対応した値を出力する」機能のこと
    • この時の入力を引数(パラメータ)と呼び、出力を戻り値と呼ぶ

算術関数

  • +、-、*、/ 算術演算子を使って計算する
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章:集合演算」 についてまとめていきます!

参考

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?