【MySQL】WorldDatabaseで操作系SQLをメモ

#はじめに
[この記事](https://qiita.com/okome-chan/items/23d186a8ff70db12fa9c)で作成したWorldDatabase on Docker(for Mac)のデータ閲覧がてら操作系のSQLをメモ化しました。
SQLの出展は[「スッキリわかる SQL 入門 ドリル215問付き! (スッキリシリーズ)」](https://www.amazon.co.jp/%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%8F%E3%81%8B%E3%82%8B-SQL-%E5%85%A5%E9%96%80-%E3%83%89%E3%83%AA%E3%83%AB215%E5%95%8F%E4%BB%98%E3%81%8D-%E3%82%B9%E3%83%83%E3%82%AD%E3%83%AA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA/dp/4844333933)。
このシリーズすごい好きですwわかりやすさは全てに勝る！

#やってみる
##データベース, テーブル, カラムの確認

```
> SHOW databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| world              |
+--------------------+

> use world
Database changed

mysql> SHOW tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city            |
| country         |
| countrylanguage |
+-----------------+

> SHOW columns FROM city;
+-------------+----------+------+-----+---------+----------------+
| Field       | Type     | Null | Key | Default | Extra          |
+-------------+----------+------+-----+---------+----------------+
| ID          | int(11)  | NO   | PRI | NULL    | auto_increment |
| Name        | char(35) | NO   |     |         |                |
| CountryCode | char(3)  | NO   | MUL |         |                |
| District    | char(20) | NO   |     |         |                |
| Population  | int(11)  | NO   |     | 0       |                |
+-------------+----------+------+-----+---------+----------------+

```

##INSERT, SELECT(WHERE), UPDATE, DELETE

```

> INSERT INTO city VALUES (99999, 'Okome', 'USA', 'Okome Chan', 99999);

> SELECT * FROM city WHERE ID = 99999;
+-------+-------+-------------+------------+------------+
| ID    | Name  | CountryCode | District   | Population |
+-------+-------+-------------+------------+------------+
| 99999 | Okome | USA         | Okome Chan |      99999 |
+-------+-------+-------------+------------+------------+

> UPDATE city SET Name = 'Okome-chan' WHERE ID = 99999;
Rows matched: 1  Changed: 1  Warnings: 0

> SELECT * FROM city WHERE Name = 'Okome-chan';
+-------+------------+-------------+------------+------------+
| ID    | Name       | CountryCode | District   | Population |
+-------+------------+-------------+------------+------------+
| 99999 | Okome-chan | USA         | Okome Chan |      99999 |
+-------+------------+-------------+------------+------------+

> DELETE FROM city WHERE ID = 99999;

> SELECT * FROM city WHERE ID = 99999;
Empty set (0.00 sec)
```

##コメントの書き方×2
```
-- コメント（行末まで有効）
/* コメント */
```

##ASで別名の定義
```
> SELECT ID, Name FROM city WHERE ID = 99999;
+-------+-------+
| ID    | Name  |
+-------+-------+
| 99999 | Okome |
+-------+-------+

> SELECT ID AS id, Name AS name FROM city WHERE ID = 99999;
+-------+-------+
| id    | name  |
+-------+-------+
| 99999 | Okome |
+-------+-------+
```

##DISTINCT, ORDER BY, LIMIT
```
> SELECT DISTINCT ID from city;
4081 rows in set (0.01 sec)

# 昇順
> SELECT DISTINCT ID FROM city ORDER BY ID ASC;

# 降順
> SELECT DISTINCT ID FROM city ORDER BY ID DESC;

# 上位3行の出力
> SELECT DISTINCT ID FROM city ORDER BY ID desc LIMIT 3;

# 列番号でカラムの代替が可能
> SELECT DISTINCT ID FROM city ORDER BY 1 ASC;

# 例：主キーを列番号でasc
> SELECT * FROM city ORDER BY 1 DESC;
```

##集合演算子(UNION, EXCEPT, INTERSECT)
適した列がないですねw

```
# UNION(和)
> SELECT Name FROM city UNION SELECT Name FROM country;

# EXCEPT(差)
> SELECT Name FROM city EXCEPT SELECT Name FROM country;

# INTERSECT(積)
> SELECT Name FROM city INTERSECT SELECT Name FROM country;
```

##計算式

```
# SELECT文の選択列リストで計算する
> SELECT Name, Population FROM country WHERE Population > 22720000 LIMIT 3;
+------------+------------+
| Name       | Population |
+------------+------------+
| Argentina  |   37032000 |
| Bangladesh |  129155000 |
| Brazil     |  170115000 |
+------------+------------+

> SELECT Name, Population, Population + 50000000 AS Population2 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+------------+-------------+
| Name       | Population | Population2 |
+------------+------------+-------------+
| Argentina  |   37032000 |    87032000 |
| Bangladesh |  129155000 |   179155000 |
| Brazil     |  170115000 |   220115000 |
+------------+------------+-------------+

# CASE演算子。BashとかのCASEと使い方は同じですね。長いので改行してます。
# when〜thenには演算子で計算式を使うこともできる。
mysql> SELECT Name, Population,
    -> CASE Name
    -> WHEN 'Argentina' THEN 'Argentina2'
    -> WHEN 'Bangladesh' THEN 'Bangladesh2'
    -> WHEN 'Brazil' THEN 'Brazil2';
    -> END AS Population3
    -> FROM country WHERE Population > 22720000 LIMIT 3
    -> ;
+------------+------------+-------------+
| Name       | Population | Population3 |
+------------+------------+-------------+
| Argentina  |   37032000 | Argentina2  |
| Bangladesh |  129155000 | Bangladesh2 |
| Brazil     |  170115000 | Brazil2     |
+------------+------------+-------------+
```

##関数
よく使いそうな気がする関数だけ試しました。
あとは都度調べる。~~めんどうやしね。~~

```
# LENGH関数
> SELECT Name, LENGTH(Name) AS Name2 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+-------+
| Name       | Name2 |
+------------+-------+
| Argentina  |     9 |
| Bangladesh |    10 |
| Brazil     |     6 |
+------------+-------+

# ROUND関数（指定行で四捨五入する）
> SELECT Name, ROUND(Population, -7) AS Population4 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+-------------+
| Name       | Population4 |
+------------+-------------+
| Argentina  |    40000000 |
| Bangladesh |   130000000 |
| Brazil     |   170000000 |
+------------+-------------+

> SELECT Name, ROUND(Population, -8) AS Population4 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+-------------+
| Name       | Population4 |
+------------+-------------+
| Argentina  |           0 |
| Bangladesh |   100000000 |
| Brazil     |   200000000 |
+------------+-------------+

# CURRENT_DATE, CURRENT_TIME
> SELECT Name, Population, CURRENT_DATE AS Population5 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+------------+-------------+
| Name       | Population | Population5 |
+------------+------------+-------------+
| Argentina  |   37032000 | 2019-12-14  |
| Bangladesh |  129155000 | 2019-12-14  |
| Brazil     |  170115000 | 2019-12-14  |
+------------+------------+-------------+

mysql> SELECT Name, Population, CURRENT_TIME AS Population5 FROM country WHERE Population > 22720000 LIMIT 3;
+------------+------------+-------------+
| Name       | Population | Population5 |
+------------+------------+-------------+
| Argentina  |   37032000 | 07:05:49    |
| Bangladesh |  129155000 | 07:05:49    |
| Brazil     |  170115000 | 07:05:49    |
+------------+------------+-------------+
```

##集計関数

```
# SUM, AVG, MAX, MIN, COUNT
> SELECT SUM(Population) AS Population5 FROM country;
+-------------+
| Population6 |
+-------------+
|  6078749450 |
+-------------+

> SELECT AVG(Population) AS Population5 FROM country;
+---------------+
| Population6   |
+---------------+
| 25434098.1172 |
+---------------+

> SELECT MAX(Population) AS Population5 FROM country;
+-------------+
| Population6 |
+-------------+
|  1277558000 |
+-------------+

> SELECT MIN(Population) AS Population5 FROM country;
+-------------+
| Population6 |
+-------------+
|           0 |
+-------------+

> SELECT COUNT(*) AS Population5 FROM country;
+-------------+
| Population6 |
+-------------+
|         239 |
+-------------+

> SELECT COUNT(Name) AS Population5 FROM country;
+-------------+
| Population6 |
+-------------+
|         239 |
+-------------+
```

##グループ化
```
> SELECT Continent, SUM(Population) AS total FROM country GROUP BY Continent;
+---------------+------------+
| Continent     | total      |
+---------------+------------+
| Asia          | 3705025700 |
| Europe        |  730074600 |
| North America |  482993000 |
| Africa        |  784475000 |
| Oceania       |   30401150 |
| Antarctica    |          0 |
| South America |  345780000 |
+---------------+------------+

# 集計結果で絞り込むにはHAVINGを使う
> SELECT Continent, SUM(Population) AS total FROM country GROUP BY Continent HAVING SUM(Population) > 0;
+---------------+------------+
| Continent     | total      |
+---------------+------------+
| Asia          | 3705025700 |
| Europe        |  730074600 |
| North America |  482993000 |
| Africa        |  784475000 |
| Oceania       |   30401150 |
| South America |  345780000 |
+---------------+------------+
```

#おわりに
金額とかの集計しやすい列はないので、そこは別でクリアすれば文句なしですね。
好き放題＆使い捨てできるDBがサッと起動する、っていう可搬性のほうが優ってます。

SQLは小文字派だったのですが、字面にすると大文字のほうが断然読みやすいですねw
以上です:bow_tone1: