【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ4（レコードの更新・削除）

##はじめに
この記事はPostgreSQLの勉強のアウトプットにポケモンずかんをつくりながら学びを深める試みです。pgAdminで作業をしているためご了承ください。
また登録されるポケモンの順序などは実際のポケモン図鑑の順番とは違いがありますので宜しくおねがいします。

####過去の記事
現在までの操作を記事化してたら謎にシリーズ化し始めてます。

- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ1（テーブルを作成）](https://qiita.com/takahirocook/items/2f5cba7db434280c5702)
- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ2（データの登録・変更）](https://qiita.com/takahirocook/items/29945efdb41e030874eb)
- [【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ3（データを取り出す）](https://qiita.com/takahirocook/items/89aba8585dcd42dd310f)
- **→ 現在の記事はここです**

筆者はポケモン第２世代までしかわからないですし、SQL初学者のため謎の動きもするかとおもいますが、それも生々しく残しながら楽しく学習していきます。

##学習の準備
####ポケモンの追加
とりあえずポケモンを20匹捕まえてきたので追加します。

```sql
INSERT INTO pokemon(
  number, name, category, type1, type2, height, weight, description,created
) VALUES
('11','フシギソウ','たねポケモン','くさ','どく','1.0','13.0','せなかの　つぼみが　おおきく　そだってくると　２ほんあしで　たつことが　できなくなるらしい。',current_timestamp),
('12','フシギバナ','たねポケモン','くさ','どく','2.0','100.0','たいようエネルギーを　えいようにして　おおきなハナが　ひらく。　ひなたに　ひきよせられるように　いどうする。',current_timestamp),
('13','リザード','かえんポケモン','ほのお',null,'1.1','19.0','もえる　しっぽを　ふりまわし　するどい　ツメで　あいてを　きりさく　あらあらしい　せいかく。',current_timestamp),
('14','リザードン','かえんポケモン','ほのお','ひこう','1.7','90.5','がんせきも　やけるような　しゃくねつの　ほのおを　はいて　やまかじを　おこすことが　ある。',current_timestamp),
('15','カメール','かめポケモン','みず',NULL,'1.0','22.5','ながいきの　シンボルとああれている。　こうらに　コケが　ついているのは　とくに　ながいきの　カメールだ。',current_timestamp),
('16','カメックス','こおらポケモン','みず',NULL,'1.6','85.5','からだが　おもたく　のしかかって　あいてを　きぜつさせる。　ピンチの　ときは　カラに　かくれる。',current_timestamp),
('17','キャタピー','いもむしポケモン','むし',null,'0.3','2.9','あたまの　しょっかくから　きょうれつな　においを　だして　てきを　おいはらい　みをまもる。',current_timestamp),
('18','トランセル','さなぎポケモン','むし',null,'0.7','9.9','しんかを　まっている　じょうたい。かたくなる　ことしか　できないので　おそわれないよう　じっとしている。',current_timestamp),
('19','バタフリー','ちょうちょポケモン','むし','ひこう','1.1','32.0','こまかく　はやく　はばたいたら　もうどくの　りんぷんが　かぜに　のって　とんでくるぞ。',current_timestamp),
('20','ビードル','けむしポケモン','むし','どく','0.3','3.2','もりや　くさちに　おおく　せいそく。　あたまの　さきに　5センチぐらいのちいさく　するどい　どくばりをもつ。',current_timestamp),
('21','コクーン','さなぎポケモン','むし','どく','0.6','10.0','じぶんでは　ほとんど　うごけないがあぶないときは　かたくなってみを　まもっているようだ。',current_timestamp),
('22','スピアー','どくばちポケモン','むし','どく','1.0','29.5','りょうてと　おしりにある 3ぼんのどくばりで　あいてを　さして　さしてさしまくって　こうげきする。',current_timestamp),
('23','ポッポ','ことりポケモン','ノーマル','ひこう','0.3','1.8','もりや　はやしに　おおく　ぶんぷ。ちじょうでも　はげしく　はばたいてすなを　かけたりする。',current_timestamp),
('24','ピジョン','とりポケモン','ノーマル','ひこう','1.1','30.0','あしの　ツメが　はったつしている。　エサの　タマタマを　つかんで100キロさきの　す　まで　はこぶ。',current_timestamp),
('25','ピジョット','とりポケモン','ノーマル','ひこう','1.5','39.5','エサを　さがすとき　すいめんすれすれを　すべるように　とんでコイキングなどを　わしづかみにする。',current_timestamp),
('26','コラッタ','ねずみポケモン','ノーマル',NULL,'0.3','3.5','まえばは　しぬまで　のびつづけるのでメンテナンスが　ひつよう。　ヤスリをよういしないと　はしらを　かじられる。',current_timestamp),
('27','ラッタ','ねずみポケモン','ノーマル',null,'0.7','18.5','およぐのが　とくい。　うしろあしにちいさな　みずかきが　ついていてかわや　ときに　うみを　わたることも。',current_timestamp),
('28','オニスズメ','ことりポケモン','ノーマル','ひこう','0.3','2.0','ハネが　みじかく　とぶのは　にがて。せわしなく　うごきまわり　くさむらのむしポケモンを　ついばんでいる。',current_timestamp),
('29','オニドリル','くちばしポケモン','ノーマル','ひこう','1.2','38.0','タフで　じきゅうりょくに　すぐれる。　おもたい　にもつを　のせたまま　まる1にち　とびつづけても　へいき。',current_timestamp),
('30','アーボ','へびポケモン','どく',null,'2.0','6.9','そだつほどに　どんどん　ながくなる。　そして　よなかは　きのえだにグルグルと　からまって　やすむ。',current_timestamp);
select * from pokemon;
```

####これから行うこと
今回から複数のテーブルを扱う勉强をするため、**ポケモン図鑑を地方ごとにテーブル分けしようと思います。**その準備のためにこれから以下のことを行います。

`1. 今まで作ったポケモン図鑑をカントー地方専用のテーブルにする。(テーブルの改名)
2. 新しくジョウト地方のポケモン図鑑のテーブルを作成してポケモンを登録する。（テーブルの作成とデータの投稿）`

今までのおさらいとはなりますが、これまで作ってきた`pokemon テーブル`はカントー地方のポケモン図鑑テーブルということで**`pokedex_kanto`**に改名し、新しく作るテーブルはジョウト地方のテーブルということで**`pokedex_joto`**と命名しようと思います。

####テーブル名の変更

テーブル名やカラムの操作は**`ALTER TABLE コマンド`**を使います。
テーブル名変更の構文はこちらです。

```
ALTER TABLE テーブル名 RENAME TO 新しいテーブル名;
```
それでは今までのテーブルを変更していきましょう。

```sql
ALTER TABLE pokemon RENAME TO pokedex_kanto;
```
実行成功したらテーブル名を確認してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/be1ce391-7ae1-90df-86ad-f5ec36c8e3db.png)
無事に改名できました。

###新しいテーブルの作成・データの登録。確認

テーブルの作成は**`CREATE　TABLE`**です。構文はこちらです。
テーブルの内容は使い回すことができそうです。

```
CREATE TABLE "テーブル名" (
カラム定義1,
カラム定義2,
カラム定義3,
 ...
)
```

データの登録は**`INSERT INTO`**です。構文はこちらです。

```
INSERT INTO "テーブル名" 
(カラム名1, カラム名2,  ・・・ )
VALUES
(カラム名1の値, カラム名2の値,  ・・・ )
```
テーブルの内容を確認するには**`SELECT`**をつかいます。

**テーブル内のすべてのデータを確認するときは**カラム指定を「すべて」という意味である**アスタリスクをつかって指定してあげればOKです。**

```
select * from データを見たいテーブル名;
```

- テーブルの作成
- データの登録
- 内容の確認

これらの一連の操作を一気にやってしまいましょう。

```sql
CREATE TABLE "pokedex_joto" (    
    number serial not null  primary key,
    name varchar(6) not null unique,
    category varchar(10) not null,
    type1 varchar(5) not null,
    type2 varchar(5),
    height float not null,
    weight float not null,
    description text check(length(description) > 5),
    created timestamp default 'now'
);
INSERT INTO pokedex_joto(
  number, name, category, type1, type2, height, weight, description,created
) VALUES
('152','チコリータ','はっぱポケモン','くさ','','0.9','6.4','あたまのはっぱから　ほのかにあまいかおりが　たふぁよう。　おとなしくてひざしを　あびるのが　だいすき。',current_timestamp),
('153','ベイリーフ','はっぱポケモン','くさ','','1.2','15.8','くびの　まわりから　はっさんするスパイスのような　かおりにはげんきを　ださせる　こうかがある。',current_timestamp),
('154','メガニウム','ハーブポケモン','くさ','','1.8','100.5','はなびら　から　はっさんされるにおいには　あらそう　きもちをしずめる　せいぶんが　ふくまれる。',current_timestamp),
('155','ヒノアラシ','ひねずみポケモン','ほのお','','0.5','7.9','おくびょうで　いつも　からだをまるめている。　おそわれると　せなかのほのおを　もえあがらせ　みをまもる。',current_timestamp),
('156','マグマラシ','かざんポケモン','ほのお','','0.9','19.0','たたかいのまえ　せなかを　むけてじぶんの　ほのおが　どれくらいすごいかを　あいてに　みせつける。',current_timestamp),
('157','バクフーン','かざんポケモン','ほのお','','1.7','79.5','いかりが　さいこうちょうのとき　さわったもの　すべて　いっしゅんで　もえあがらせるほどに　あつい。',current_timestamp),
('158','ワニノコ','おおあごポケモン','みず','','0.6','9.5','ちいさいながらも　あばれんぼう。　めのまえで　うごくものが　あれば　とにかく　かみついてくる。',current_timestamp),
('159','アリゲイツ','おおあごポケモン','みず','','1.1','25.0','キバは　ぬけても　つぎから　つぎにはえてくる。　いつも　くちのなかには　48ぽんの　キバがそろっている。',current_timestamp),
('160','オーダイル','おおあごポケモン','みず','','2.3','88.8','ふだんは　ゆっくりとした　うごきだがえものに　かみつくときはめにも　とまらない　スピードだ。',current_timestamp),
('161','オタチ','みはりポケモン','ノーマル','','0.8','6.0','みはりやくは　するどく　ないたりしっぽで　じめんを　たたいたりしてなかまに　きけんを　しらせる。',current_timestamp),
('162','オオタチ','どうながポケモン','ノーマル','','1.8','32.5','ははおやは　ほそながい　からだでこどもを　つつみこみ　ねむらせる。　はやい　うごきで　てきを　おいこむ。',current_timestamp),
('163','ホーホー','ふくろうポケモン','ノーマル','ひこう','0.7','21.2','いつも　いっぽんあしで　たっている。　あしを　いれかえる　しゅんかんは　すばやくて　なかなか　みられない。',current_timestamp),
('164','ヨルノズク','ふくろうポケモン','ノーマル','ひこう','1.6','40.8','とくしゅな　つくりの　りょうめは　わずかな　ひかりさえ　あれば　くらやみでも　ひるのように　みえる。',current_timestamp),
('165','レディパ','いつつぼしポケモン','むし','ひこう','1.0','10.8','おくびょうで　つねに　むれていないとふあん。　せなかのもようは　１ぴき１ぴき　びみょうに　ちがう　かたち。',current_timestamp),
('166','レディアン','いつつぼしポケモン','むし','ひこう','1.4','35.6','ほしあかりが　エネルギーと　いわれるがふつうに　きのみも　だいこうぶつ。　ひるまは　くさに　くるまって　ねてる。',current_timestamp),
('167','イトマル','いとはきポケモン','むし','どく','0.5','8.5','こうぶつの　アブリーが　すにかかるまで　ひたすら　まちつづける。　じつに　しんぼうづよいポケモン',current_timestamp),
('168','アリアドス','あしながポケモン','むし','どく','1.1','33.5','アリアドスの　いとを　つたってはたを　おる　ちいきも　ある。　じょうぶな　ぬので　こうひょうだ。',current_timestamp),
('169','クロバット','こうもりポケモン','どく','ひこう','1.8','75.0','りょうあしも　はねになった　けっか　ちじょうでの　うごきは　にがて。　はいずりまわることしか　できない。',current_timestamp),
('170','チョンチー','あんこうポケモン','みず','でんき','0.5','12.0','ひれが　へんかして　できた　しょくしゅは　それぞれ　プラスと　マイナスの　でんきが　ながれている。',current_timestamp);
select * from pokedex_joto;
```

####実行結果

新しく**`pokedex_joto`**テーブルが作成されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/5103d126-7ec1-1bb7-a0b4-5d611946b851.png)

投稿内容も問題なさそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/c3907f0d-18ea-e1f6-5f02-048dfe1fae93.png)

長くなりましたが準備は完了したので、本題である学習に移っていきましょう。

##【UPDATE文】登録したデータを変更する。

###【問題発覚】nullと空の文字列

大変申し訳ありません、だいぶポケモンの数が増えてきましたが、、実は今までの登録内容に重大ながありました。

**type2（ポケモン２つめのタイプ）の値に「null」が入力されています。**

ヒトカゲのように「タイプが'ほのお'だけで**２つめのタイプを持っていないポケモン**」という場合には、タイプ２には入力する内容がありません。

ですが値が「null」だと、**Javaなどの言語と結びつけたときに悪さをしてしまう**可能性があります。( Javaは文字列を扱う言語のため。)

そのため、「データがない」場合は、空の文字列を挿入する**`''`（ クオーテーション2つ ）**が正しかったようです。

そのため、**`UPDATE文`**を使って、値が**`null`**の部分を**`''`**に変更していく作業を行っていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/7e715866-78e9-5c71-d5b6-51944705277c.png)


###UPDATE文とは
データベース内のデータを変更、更新する命令です。
UPDATE文を使用することによって、すでに登録したデータの変更を行うことができます。手順としては...

1. **`UPDATE`**宣言をして、**対象のテーブル**を指定する。
2. **`SET`**宣言をして、**対象のカラムと変更内容を記述**していきます。
3. **`WHERE`**を使って、**どこの行を変更してあげるかを指定**してあげます。（`指定しない場合はカラム内すべてのデータが変更`されてしまうため、理由がない限りは指定するクセをつけましょう！）

###基本構文

```
UPDATE "テーブル名"
SET
"カラム名" = 値
WHERE
カラム名(primary keyなど) = 変更したい行の値
```
まずは試しにリザードのtype2がnullになっているので、これを空文字に更新してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/b237ad49-a096-4f50-9aa4-9030a4e9c041.png)

- テーブル名はpokedex_kanto
- type2の値は空文字
- リザードのnumberは13
- SELECTで内容を確認

一連のコマンドを入力します。

```sql
UPDATE pokedex_kanto
SET
type2 = ''
WHERE
number = 13;
SELECT * FROM pokedex_kanto;
```
####実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/bc04c7a2-a680-804d-ad5b-8d278a89c114.png)

リザードのtype2の値が **`null`**から 空の文字列に変わりました！
でもまだ他にも**`null`**の値が与えられているものがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/50262048-3743-8c97-bd4e-9437074caa72.png)

###IS NULL演算子(IS NOT NULL演算子)
**`WHERE`**でターゲットを「値が**`null`**のもの」に指定して一気に更新します！
値がNULLの値を扱うときは通常の演算子ではなく、NULL専用の演算子を使う必要があります。

- 値が**`NULL`**のものはWHEREのあとに**`IS NULL`**
- 値が**`NULL`**以外のものはWHEREのあとに**`IS NULL`**

`「 type2の値が　nullのものは 空文字に更新 」`の場合、このような表現をしてあげます。

```sql
UPDATE pokedex_kanto
SET
type2 = ''
WHERE
type2 IS NULL;
SELECT number, name, type2 FROM pokedex_kanto;
```
####実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/e5045968-e1f3-6459-1847-d58dbaba846e.png)
これでオッケーですね！

###演算子を使った更新

更新のやり方次第では、値に文字や数字を足したり引いたりすることも可能です。
練習を兼ねて「ポケモンのnumber全てに100を足す」といったことをやってみましょう。
**`SET宣言`**のあとに**「numberは今の値に100を足したもの」**という記述をし、**`WHERE`を指定しないことで、すべての値に適用させます。**

```sql
UPDATE pokedex_kanto SET number = number + 0;
```
####実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/e6f56aa4-c583-a05e-94a1-5d11ed48be1d.png)
できました！

流れで、そろそろ今まで適当に振っていたポケモンのnumberも公式を意識した形にしていきます。

###【復習】カラムの型を変更する
自分でポケモン図鑑を作りながら感じたのは、ポケモンのnumber（ナンバー）の型は、serial(連番)よりもINTのほうが扱いやすいです。オリジナルもそれぞれ個別で振られていますし。
ということで、復習も兼ねてnumberの型を変更し、そのあとで改めて新しく値を降っていきましょう。

カラムの変更は**`ALTER TABLEコマンド`**を使いました。
**`ALTER TABLEコマンド`**の主な使用例は以下です。

- テーブル名を変更
- カラム名を変更
- スキーマを変更
- カラムの追加
- カラムの削除
- カラムのデータ型の変更
- 制約の追加と削除

以前自分が書いた[【PostgreSQL】ポケモンずかんをつくってSQLを学ぶ2（データの登録・変更）](https://qiita.com/takahirocook/items/29945efdb41e030874eb)に他の事例でのより詳しい使用方法は書いてありますので良ければこちらもご覧ください。

**型の変更をする場合はこちらの構文です。**

```
ALTER TABLE テーブル名 ALTER カラム名 TYPE 型の定義;
```
numberの型を改めて定義し直しましょう。

```sql
ALTER TABLE pokedex_kanto ALTER number TYPE INT;
```
####実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/cb682391-8908-d996-316c-1e719de65550.png)
numberがINT型になりました！

###primary keyの削除・追加
練習でプライマリーキーの追加と削除をしてみます。
####追加
追加の場合の構文はこちらです。

```sql
ALTER TABLE pokedex_kanto ADD primary key(number);
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/275ddb05-7b77-e9e8-1ce3-ecc37cb50455.png)
追加オッケーです！

プライマリーキーの削除はやや特殊な形になります。
最後のテーブル名の語尾にアンダーバーでpkeyとつなぐようです。
####削除

```
ALTER TABLE テーブル名 DROP CONSTRAINT テーブル名_pkey;
```
ポケモン図鑑テーブルからプライマリーキーを削除してみます。

```sql
ALTER TABLE pokedex_kanto DROP CONSTRAINT pokedex_kanto_pkey;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/c58255eb-2568-c9cd-5ec0-7397571e46a1.png)
できました！

```SQL
UPDATE pokedex_kanto SET number = 1 WHERE name = 'フシギダネ';
UPDATE pokedex_kanto SET number = 2 WHERE name = 'フシギソウ';
UPDATE pokedex_kanto SET number = 3 WHERE name = 'フシギバナ';
UPDATE pokedex_kanto SET number = 4 WHERE name = 'ヒトカゲ';
UPDATE pokedex_kanto SET number = 5 WHERE name = 'リザード';
UPDATE pokedex_kanto SET number = 6 WHERE name = 'リザードン';
UPDATE pokedex_kanto SET number = 7 WHERE name = 'ゼニガメ';
UPDATE pokedex_kanto SET number = 8 WHERE name = 'カメール';
UPDATE pokedex_kanto SET number = 9 WHERE name = 'カメックス';
UPDATE pokedex_kanto SET number = 10 WHERE name = 'キャタピー';
UPDATE pokedex_kanto SET number = 11 WHERE name = 'トランセル';
UPDATE pokedex_kanto SET number = 12 WHERE name = 'バタフリー';
UPDATE pokedex_kanto SET number = 13 WHERE name = 'ビードル';
UPDATE pokedex_kanto SET number = 14 WHERE name = 'コクーン';
UPDATE pokedex_kanto SET number = 15 WHERE name = 'スピアー';
UPDATE pokedex_kanto SET number = 16 WHERE name = 'ポッポ';
UPDATE pokedex_kanto SET number = 17 WHERE name = 'ピジョン';
UPDATE pokedex_kanto SET number = 18 WHERE name = 'ピジョット';
UPDATE pokedex_kanto SET number = 19 WHERE name = 'コラッタ';
UPDATE pokedex_kanto SET number = 20 WHERE name = 'ラッタ';
UPDATE pokedex_kanto SET number = 21 WHERE name = 'オニスズメ';
UPDATE pokedex_kanto SET number = 22 WHERE name = 'オニドリル';
UPDATE pokedex_kanto SET number = 23 WHERE name = 'アーボ';
UPDATE pokedex_kanto SET number = 25 WHERE name = 'ピカチュウ';
UPDATE pokedex_kanto SET number = 52 WHERE name = 'ニャース';
UPDATE pokedex_kanto SET number = 143 WHERE name = 'カビゴン';
UPDATE pokedex_kanto SET number = 144 WHERE name = 'フリーザー';
UPDATE pokedex_kanto SET number = 145 WHERE name = 'サンダー';
UPDATE pokedex_kanto SET number = 146 WHERE name = 'ファイアー';
UPDATE pokedex_kanto SET number = 150 WHERE name = 'ミュウツー';
SELECT number, name, type2 FROM pokedex_kanto ORDER BY number ASC;
```
####実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/2bf8f900-3e1c-98fa-e03c-1ef81cf0572c.png)
成功です！これでだいぶオリジナルに近づいてきました。

##レコードの集計

結構ポケモン増えてきましたが、今何匹いるのか確認してみましょう。
一番左の行数を追ってもいいですが、テーブルにレコード（登録されているもの）が何件あるか表示させるための構文はこちらです。

```
select count(*) from テーブル名;
```
現在ポケモン図鑑に登録されている数を集計します。

```sql
select count(*) from pokedex_kanto;
```
####実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/613675/07fa9ee6-a10b-3307-1f21-9f58e1afe282.png)
カントーだけであと121匹もいました...

図鑑を完成させるのが先か、SQLをマスターするのが先か・・