freedom-_-qの勉強履歴

メモ書きが主になるかと思います。勉強強制のために一日一記事目指してます。頭良くないので間違いが多々あるかと思います。

MySQLチュートリアル(取得編)

対象テーブルの準備

MySQLチュートリアル(作成編)で作成したテーブルに少し追加する。
具体的には、性別を示すカラムをnameの後ろに追加する。LGBTQを考慮してBOOLEANは使わない。

mysql> ALTER TABLE users ADD SEX VARCHAR(1) AFTER name;
Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0

SELECT * FROM users;
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 001 | Yamada Tarou   | NULL | 2000-01-01 |
| 002 | Yamada Hanako  | NULL | 2000-02-02 |
| 003 | Yamada Jirou   | NULL | 2000-03-03 |
| 004 | Yamada Ichirou | NULL | 2020-04-04 |
+-----+----------------+------+------------+
4 rows in set (0.00 sec)

mysql> UPDATE users SET sex='M';
Query OK, 4 rows affected (0.00 sec)
Rows matched: 4  Changed: 4  Warnings: 0

mysql> UPDATE users SET sex='W' where name='Yamada Hanako';
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> SELECT * FROM users;
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 001 | Yamada Tarou   | M    | 2000-01-01 |
| 002 | Yamada Hanako  | W    | 2000-02-02 |
| 003 | Yamada Jirou   | M    | 2000-03-03 |
| 004 | Yamada Ichirou | M    | 2020-04-04 |
+-----+----------------+------+------------+
4 rows in set (0.00 sec)

データの取得

オプションが大量にあるので、先ずは基本系で慣れる。
自分が理解しやすいように書いているため、正確なSELECT文は公式リファレンス参照。

SELECT {カラム名1, カラム名2, ... | *}
FROM {テーブル名}
WHERE {条件1 AND | OR 条件2 ...}
ORDER BY {カラム名} [DESC | ASC]

性別が男性である名前のみ取得

mysql> SELECT name FROM users WHERE sex='M';
+----------------+
| name           |
+----------------+
| Yamada Tarou   |
| Yamada Jirou   |
| Yamada Ichirou |
+----------------+
3 rows in set (0.00 sec)

誕生日が2020-01-01より昔の全カラムの取得

mysql> SELECT * FROM users WHERE birth < '2020-01-01';
+-----+---------------+------+------------+
| id  | name          | sex  | birth      |
+-----+---------------+------+------------+
| 001 | Yamada Tarou  | M    | 2000-01-01 |
| 002 | Yamada Hanako | W    | 2000-02-02 |
| 003 | Yamada Jirou  | M    | 2000-03-03 |
+-----+---------------+------+------------+
3 rows in set (0.00 sec)

誕生日が2000-02-01~2000-04-01の全カラムの取得

期間指定にはBETWEEN {A} AND {B}

SELECT * FROM users WHERE birth BETWEEN '2000-02-01' AND '2000-04-01';
+-----+---------------+------+------------+
| id  | name          | sex  | birth      |
+-----+---------------+------+------------+
| 002 | Yamada Hanako | W    | 2000-02-02 |
| 003 | Yamada Jirou  | M    | 2000-03-03 |
+-----+---------------+------+------------+
2 rows in set (0.00 sec)

誕生日を降順で並び替えて全カラム取得

mysql> SELECT * FROM users ORDER BY birth DESC;
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 004 | Yamada Ichirou | M    | 2020-04-04 |
| 003 | Yamada Jirou   | M    | 2000-03-03 |
| 002 | Yamada Hanako  | W    | 2000-02-02 |
| 001 | Yamada Tarou   | M    | 2000-01-01 |
+-----+----------------+------+------------+
4 rows in set (0.00 sec)

idが偶数の全カラム取得

MOD関数が用意されているため、そちらを使う。

mysql> SELECT * FROM users WHERE MOD(id,2)=0;
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 002 | Yamada Hanako  | W    | 2000-02-02 |
| 004 | Yamada Ichirou | M    | 2020-04-04 |
+-----+----------------+------+------------+
2 rows in set (0.00 sec)

名前がrouで終わる全カラムの取得

LIKEではワイルドカードが通常と異なる。

一般的なワイルドカード MySQLワイルドカード
* %
? _

%と_そのものを使いたい時は、エスケープシーケンス\を使用する。

mysql> SELECT * FROM users WHERE name LIKE '%rou';
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 001 | Yamada Tarou   | M    | 2000-01-01 |
| 003 | Yamada Jirou   | M    | 2000-03-03 |
| 004 | Yamada Ichirou | M    | 2020-04-04 |
+-----+----------------+------+------------+
3 rows in set (0.00 sec)

jirou以外の名前がrouで終わる全カラムの取得

正規表現で取得できれば、大体何とかなるはず。

mysql> SELECT * FROM users WHERE name REGEXP '.+(Ji|Ta)rou';
+-----+--------------+------+------------+
| id  | name         | sex  | birth      |
+-----+--------------+------+------------+
| 001 | Yamada Tarou | M    | 2000-01-01 |
| 003 | Yamada Jirou | M    | 2000-03-03 |
+-----+--------------+------+------------+
2 rows in set (0.01 sec)

2条件のゴリ押しや_でもできる。 やり方が複数ある場合、対応できる幅が広がるから複数の方法を覚えるように心がけている。

mysql> SELECT * FROM users WHERE name LIKE '%Tarou' OR name LIKE '%Jirou';
+-----+--------------+------+------------+
| id  | name         | sex  | birth      |
+-----+--------------+------+------------+
| 001 | Yamada Tarou | M    | 2000-01-01 |
| 003 | Yamada Jirou | M    | 2000-03-03 |
+-----+--------------+------+------------+
2 rows in set (0.00 sec)
mysql> SELECT * FROM users WHERE name LIKE '% __rou';
+-----+--------------+------+------------+
| id  | name         | sex  | birth      |
+-----+--------------+------+------------+
| 001 | Yamada Tarou | M    | 2000-01-01 |
| 003 | Yamada Jirou | M    | 2000-03-03 |
+-----+--------------+------+------------+
2 rows in set (0.01 sec)

idが大きい順で2件を昇順で取得

idを降順にして2件取り出して昇順にする。 なんか変な感じするけど、以下クエリで解決できる。

(SELECT * FROM users ORDER BY id DESC LIMIT 2) ORDER BY id;
+-----+----------------+------+------------+
| id  | name           | sex  | birth      |
+-----+----------------+------+------------+
| 003 | Yamada Jirou   | M    | 2000-03-03 |
| 004 | Yamada Ichirou | M    | 2020-04-04 |
+-----+----------------+------+------------+
2 rows in set (0.00 sec)

今日はこの辺で...