[MySQL]SQLとクエリについて

# はじめに

SQLについて学習したので見ていきたいと思います。

種類が。。色々あり難しいですが忘れないよう今回も書いていきます。

データベースによって書き方が若干違うようなのですが私はMySQLを使用しています。

# SQLとクエリ

`SQLとは`　　　データベースを操作するための言語、命令するための言語

`クエリとは！`　　データベースからデータを抽出したりデータを抽出したり
　　　　　　　  操作したりする命令文のこと（「SQL文」）

(慣習的にSQLが用意している命令を書くときは大文字に、自分でつけるテーブルやカラムを書くときは小文字にすることが多い)

 この内容については、[「クエリとSQLの違い」](https://teratail.com/questions/33625) で以下のように説明されています。
>SQL は Structured Query Language の略（略、というのは正しくないですね、そういう>語が語源になっている名前、ですかね。SQL の Q は Query の Q ですね）で、HTML などと同様、言語仕様の名前です。正しくは、「SQL という言語仕様に則って書いたこれこれこういうクエリを投げる」とかいうべきですが、それを慣習的に「こういう SQL を投げる」（ここでいう「投げる」は RDBMS にリクエストするという意味です）と言ったりします。
「PHP の文法に則って書かれたこれこれこういうスクリプトを実行する」というのを「こういう PHP を実行する」と言っているみたいなものですから、かなり間違った言い方だと思いますが、かなり普及していますね。


・・・そうか！！！

# SQLの種類

今回はその中で二つを学習したので記述していきます。

## DDL(Data Definition Language)
データベースのオブジェクトの生成や削除変更を行うコマンド

「Definition」　定義、記述、語義、定義すること、定義づけ

`今回使用したもの`

- DROP : (削除)
- CREATE : (データベース、テーブル作成)
- ALTER : (定義変更)
- TRUNCATE 
- RENAME 

## DML(Data Manipulation Language)

テーブルに対するデータの取得・追加・更新・削除を行うコマンド

「Manipulation」　巧みな操作、（データ、画像などの）処理

`今回使用したもの`

- SELECT : (データ検索、取得)
- INSERT : (挿入)
- UPDATE : (更新)
- DELETE : (削除)


#### もっと詳しく↓
[優秀な開発者になりたい。](https://gr8developer.blogspot.com/2017/12/ddldmldcltcl.html)


# 色々使ってみる


### 「DESC」

テーブルの構造を確認できます。

```sql

mysql> DESC maps;
+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| address    | varchar(255) | YES  |     | NULL    |                |
| name       | varchar(255) | YES  |     | NULL    |                |
| num        | int(11)      | YES  |     | NULL    |                |
| created_at | datetime(6)  | NO   |     | NULL    |                |
| updated_at | datetime(6)  | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)
```

### 「SHOW」　

一覧を確認してみます。

```sql

mysql> SHOW DATABASES;

--　（たくさんあるので割愛）

```

```sql
mysql> SHOW TABLES;
+----------------------------------+
| Tables_in_experiment_development |
+----------------------------------+
| ar_internal_metadata             |
| maps                             |
| schema_migrations                |
+----------------------------------+
3 rows in set (0.00 sec)
```


```sql
mysql> SHOW COLUMNS FROM maps;

+------------+--------------+------+-----+---------+----------------+
| Field      | Type         | Null | Key | Default | Extra          |
+------------+--------------+------+-----+---------+----------------+
| id         | bigint(20)   | NO   | PRI | NULL    | auto_increment |
| address    | varchar(255) | YES  |     | NULL    |                |
| name       | varchar(255) | YES  |     | NULL    |                |
| num        | int(11)      | YES  |     | NULL    |                |
| created_at | datetime(6)  | NO   |     | NULL    |                |
| updated_at | datetime(6)  | NO   |     | NULL    |                |
+------------+--------------+------+-----+---------+----------------+
6 rows in set (0.01 sec)
```
### 「USE」　

どのデータベースを使用するかを指定します。

```sql

mysql> USE experiment_development;

```


### 「DROP」　削除するために使用



```sql


DROP TABLE IF EXISTS maps;

--もしmapsがなかったら　IF EXISTSを使用しないとエラーになります。
```

### 「CREATE」 データベースやテーブルを作成するために使用
 

```sql

CREATE TABLE maps (
  address VARCHAR(140), --日本語英語関係なく文字列を１４０文字にする
  num INT UNSIGNED,
  dec DECIMAL(4,2) --全体で４桁だよそのうち小数点以下は２桁だよ,UNSIGNEDは範囲を広げるためのもの
);
```

### 「ALTER」　定義変更するために使用

```sql
mysql> SELECT * FROM maps;
+----+--------------------+---------+------+----------------------------+----------------------------+
| id | address            | name    | num  | created_at                 | updated_at                 |
+----+--------------------+---------+------+----------------------------+----------------------------+
|  1 | 青森県青森市       | michiko |    8 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+--------------------+---------+------+----------------------------+----------------------------+
1 row in set (0.00 sec)
```

カラムを追加します。

```sql
                        --カラム名↓  --型↓
mysql> ALTER TABLE maps ADD school VARCHAR(255);
                     -- 複数追加する場合は「ADD」の後に「（カラム名、型、カラム名、型・・・）」

Query OK, 0 rows affected (0.06 sec)
Records: 0  Duplicates: 0  Warnings: 0
```

追加されたか確認してみます。


```sql
mysql> SELECT * FROM maps;
+----+--------------------+---------+------+----------------------------+----------------------------+--------+
| id | address            | name    | num  | created_at                 | updated_at                 | school |
+----+--------------------+---------+------+----------------------------+----------------------------+--------+
|  1 | 青森県青森市       | michiko |    8 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 | NULL   |
+----+--------------------+---------+------+----------------------------+----------------------------+--------+
1 row in set (0.00 sec)
```

後ろに追加されています。

追加位置を指定したい場合は　「AFTER」 や 「FIRST」 を使用します。

 ```sql
ALTER TABLE maps ADD school VARCHAR(255) AFTER id;

ALTER TABLE maps ADD school VARCHAR(255) FIRST;
```
カラムを削除します。

```sql
mysql> ALTER TABLE maps DROP school;

Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0
```

削除されたか確認してみます。

```sql
mysql> SELECT * FROM maps;
+----+--------------------+---------+------+----------------------------+----------------------------+
| id | address            | name    | num  | created_at                 | updated_at                 |
+----+--------------------+---------+------+----------------------------+----------------------------+
|  1 | 青森県青森市       | michiko |    8 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+--------------------+---------+------+----------------------------+----------------------------+
1 row in set (0.00 sec)
```
名前を変えます。

```sql
mysql> ALTER TABLE maps CHANGE num points INT;

Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0
```

確認します。

```sql
mysql> SELECT * FROM maps;
+----+--------------------+---------+--------+----------------------------+----------------------------+
| id | address            | name    | points | created_at                 | updated_at                 |
+----+--------------------+---------+--------+----------------------------+----------------------------+
|  1 | 青森県青森市       | michiko |      8 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+--------------------+---------+--------+----------------------------+----------------------------+
1 row in set (0.00 sec)
```


### 「TRUNCATE」

新しくデータを入れた場合、一度使われた連番は使われずに新しいものが使われます。

もし、連番を付けなおしたいのであれば、テーブルを一度削除して再作成しなくてはいけません。
中身を確認します。

```sql
mysql> SELECT * FROM maps;
+----+-----------------------+---------+------+----------------------------+----------------------------+
| id | address               | name    | num  | created_at                 | updated_at                 |
+----+-----------------------+---------+------+----------------------------+----------------------------+
|  1 | 北海道札幌市          | hanako  |    1 | 2020-12-31 03:20:50.099168 | 2020-12-31 03:20:50.099168 |
|  3 | 東京都千代田区        | sumi    |    1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
|  4 | 福岡県福岡市          | takeshi |    6 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+-----------------------+---------+------+----------------------------+----------------------------+
3 rows in set (0.00 sec)
```

一度削除して再作成します。

```sql
mysql> TRUNCATE TABLE maps;

Query OK, 0 rows affected (0.01 sec)
```

空になりました。

```sql
mysql> SELECT * FROM maps;

Empty set (0.00 sec)
```

新しい値を入れてみます。

```sql
mysql> INSERT INTO maps (address, name, num ) VALUES ('青森県青森市', 'michiko', 8);

Query OK, 1 row affected, 2 warnings (0.01 sec)
```

連番が　「１」　になりました。

```sql
mysql> SELECT * FROM maps;
+----+--------------------+---------+------+----------------------------+----------------------------+
| id | address            | name    | num  | created_at                 | updated_at                 |
+----+--------------------+---------+------+----------------------------+----------------------------+
|  1 | 青森県青森市       | michiko |    8 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+--------------------+---------+------+----------------------------+----------------------------+
1 row in set (0.00 sec)
```


### 「RENAME」

テーブルの名前を後から変えたい場合に使用します。

```sql
mysql> SHOW TABLES;
+----------------------------------+
| Tables_in_experiment_development |
+----------------------------------+
| ar_internal_metadata             |
| maps                             |
| schema_migrations                |
+----------------------------------+
3 rows in set (0.00 sec)
```

使用してみます。

```sql
mysql> ALTER TABLE maps RENAME posts;

Query OK, 0 rows affected (0.00 sec)
```

確認します。

```sql
mysql> SHOW TABLES;
+----------------------------------+
| Tables_in_experiment_development |
+----------------------------------+
| ar_internal_metadata             |
| posts                            |
| schema_migrations                |
+----------------------------------+
3 rows in set (0.00 sec)
```

<br>
<br>




### 「SELECT」　データを検索、取得

中身を確認してみます。
・・・入りました！！

```sql
mysql> SELECT * FROM maps;
+----+-----------------------+--------+------+----------------------------+----------------------------+
| id | address               | name   | num  | created_at                 | updated_at                 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
|  1 | 北海道札幌市          | hanako |    1 | 2020-12-31 03:20:50.099168 | 2020-12-31 03:20:50.099168 |
|  2 | 沖縄県那覇市          | taro   |    3 | 2020-12-31 03:22:21.507907 | 2020-12-31 03:22:21.507907 |
|  3 | 東京都千代田区        | sumi   |    1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
3 rows in set (0.00 sec)
```

### 「INSERT」　挿入

追加で情報を入れてみます。

```sql

mysql> INSERT INTO maps (address, name, num) VALUES ('東京都千代田区','sumi', 1);
                             
Query OK, 1 row affected, 2 warnings (0.01 sec)

```

確認します。


```sql
mysql> select * from maps;
+----+-----------------------+--------+------+----------------------------+----------------------------+
| id | address               | name   | num  | created_at                 | updated_at                 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
|  1 | 北海道札幌市          | hanako |    1 | 2020-12-31 03:20:50.099168 | 2020-12-31 03:20:50.099168 |
|  2 | 沖縄県那覇市          | taro   |    3 | 2020-12-31 03:22:21.507907 | 2020-12-31 03:22:21.507907 |
|  3 | 東京都千代田区        | sumi   |    1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
3 rows in set (0.00 sec)
```

### 「UPDATE」　更新


「５」 足して出力するなら

```sql
UPDATE posts SET num = num + 5;
```

条件をつけて出力することもできます。
「num」　が　「２」　以上ならば　「５」　を足します。

```sql
mysql> UPDATE maps SET num = num + 5 WHERE num >= 2;

Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
```

確認します。

```sql
mysql> SELECT * FROM maps;
+----+-----------------------+--------+------+----------------------------+----------------------------+
| id | address               | name   | num  | created_at                 | updated_at                 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
|  1 | 北海道札幌市          | hanako |    1 | 2020-12-31 03:20:50.099168 | 2020-12-31 03:20:50.099168 |
|  2 | 沖縄県那覇市          | taro   |    8 | 2020-12-31 03:22:21.507907 | 2020-12-31 03:22:21.507907 |
|  3 | 東京都千代田区        | sumi   |    1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
3 rows in set (0.00 sec)
```
### 「DELETE」　削除

通常は条件をつけて削除します。

```sql
mysql> DELETE FROM maps WHERE num >= 5;

Query OK, 1 row affected (0.00 sec)
```

確認します。

```sql
mysql> SELECT * FROM maps;
+----+-----------------------+--------+------+----------------------------+----------------------------+
| id | address               | name   | num  | created_at                 | updated_at                 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
|  1 | 北海道札幌市          | hanako |    1 | 2020-12-31 03:20:50.099168 | 2020-12-31 03:20:50.099168 |
|  3 | 東京都千代田区        | sumi   |    1 | 0000-00-00 00:00:00.000000 | 0000-00-00 00:00:00.000000 |
+----+-----------------------+--------+------+----------------------------+----------------------------+
2 rows in set (0.00 sec)
```


# まとめ

よく出てくるであろうものを自分で出力したりしてみました。

慣れるようもう少し動かしていきます。

今度は検索方法についたりなどを書いていってみたいと思います。

最後に「INSERT」で情報を入れた時に必ず「warning」が出ていたが、日時を入れていなかったために出てきたものでした。
「0」になって出力されてます。

```sql
mysql> SHOW WARNINGS;
+---------+------+-------------------------------------------------+
| Level   | Code | Message                                         |
+---------+------+-------------------------------------------------+
| Warning | 1364 | Field 'created_at' doesn't have a default value |
| Warning | 1364 | Field 'updated_at' doesn't have a default value |
+---------+------+-------------------------------------------------+
2 rows in set (0.00 sec)

```

こんな感じでメッセージも見れるんですね！なるほど。。

これもまた確認しよう・・・！！　今日はここまで！

#### もっと詳しく↓

[[MySQL]SQL実行時に発生したwarningを確認する方法](https://www.t3a.jp/blog/web-develop/mysql-show-warnings/)

[MySQL 5.6 リファレンスマニュアル ](https://dev.mysql.com/doc/refman/5.6/ja/show-warnings.html)