Quantcast
Channel: 初心者タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 21085

サザエさんと学ぶSQL構文(参照クエリチートシート)

$
0
0

Introduction

きっかけ

データベースの勉強をしようということで、入門書を読みました。
そこでデータベースの入門書を元に、自分への備忘録としてまとめます。
しかしただ入門書と同じ実験データで話しても面白くないということで、サザエさんのキャラクターを用いて解説いたします。1

要約

本稿では、SQLの基本的な参照コマンドと実行結果を画像を用いて紹介します。

<話すこと>
・SQLデータベースの操作(参照)
・SQLのデータベースの作り方
・ビューを作成する方法とメリット
に関する構文の紹介
磯野家、フグ田家の家族構成

<話さないこと>2
・環境構築に関すること
・SQLデータベースの操作(集約、整列)
・サブクエリの用法
・外部結合、内部結合
・かもめ小学校のこと、伊佐坂先生についてなど

自己紹介

smile.jpg

自己紹介ページ

環境情報
macOS Catalina ver:10.15.3
SQL Ver 8.0.19 for osx10.15 on x86_64 (Homebrew)

対象者

・SQLの初心者の方
・1を聞いて10を理解できるエンジニア
・mysql系データベースを使いたい方
Macユーザーの人
・サザエさんを過去見たことがある方。

非対象者

・SQLが超お得意な人
・説明下手な筆者を攻撃しようとするエンジニア
・mysql以外のDBMS系データベースを使いたい方3
Windowsユーザーの人 4
・サザエさんのファン

Let's Start

1. データベースの操作方法

今回は、以下のデータベースを操作していきます。

qiita_select_tables.png

Case1:表から列名を指定して取得します。

実際の想定例・・・
サザエさんには、どんな名前のキャラがいるのか忘れた時。

SELECTnameFROMFamily;

Family表のname列を取得します。

qiita_select_name_from_table.png

Case2:表から複数の列名を指定して取得します。

実際の想定例・・・
サザエさんに登場するキャラの年齢を知りたい時。

SELECTname,ageFROMFamily;

Family表のname列とage列を取得します。

qiita_select_name_age_from_table.png

Error:
複数選択するときの注意として、列名全てにコンマを付すと、エラーを吐きます。
エラー例
SELECT name, age, FROM Family;
僕も何度も苦しみました。気をつけてください!

qiita_select_names_error.png

Case3:表から列名を指定して重複を除いて取得します。

実際の想定例・・・
サザエさんに登場するキャラってどんな性別があるっけ?と、気になって気になって夜も眠れないとき。

SELECTDISTINCTgenderFROMFamily;

Family表のgender列を取得します。

qiita_select_distinct_gender.png

Case4:表から複数の列から、重複を除いて取得します。

実際の想定例・・・
サザエさんに登場するキャラが、それぞれの性別で昼間どんなことしてるのか知りたくなったとき。

SELECTDISTINCTgender,categoryFROMFamily;

Family表から重複を除いてgender列とcategory列を取得します。

qiita_select_distinct_gender_category.png

Case5:表から条件に該当するデータを検索して、取得します。

実際の想定例・・・
サザエさんに登場する女性キャラを、知りたくなったとき。

SELECTname,genderFROMFamilyWHEREgender='女';

Family表からgender列が「女」という条件のname列とgender列を取得します。

qiita_select_name_gender_where_female.png

Case6:表からNULLが含まれるデータを検索して、取得します。

実際の想定例・・・
サザエさんに登場するキャラのなかで、血液型がわからない人は誰なのか気になったとき。5

SELECTname,bloodFROMFamilyWHEREbloodISNULL;

Family表からblood列がNULLであるname列とblood列を取得します。

qiita_select_name_blood_where_is_null.png

Column:
NULL以外のものが知りたい時は、
SELECT name, blood FROM Family WHERE blood IS NOT NULL;
をご利用ください。

Case7:表から任意の値からの大小を指定したデータを検索して、取得します。

実際の想定例・・・
サザエさんに登場するキャラのなかで、20才以上は誰なのか気になったとき。

SELECTname,ageFROMFamilyWHEREage>=20;

Family表からage列が20以上であるname列とage列を取得します。

qiita_select_name_age_where_20over.png

Error:
20歳以上を記述するときに、「>=」じゃなくて、「=>」とすると、エラーを出力します。
SELECT name, age FROM Family WHERE age => 20;

qiita_select_name_age_error.png

参考:
他の比較演算子の場合は以下のように記述します。

等しいとき「=」 (20歳であるとき)

SELECTname,ageFROMFamilyWHEREage=20;

等しくない「<>」 (20歳でないとき)

SELECTname,ageFROMFamilyWHEREage<>20;

より大きい「>」 (20歳より大きいとき)

SELECTname,ageFROMFamilyWHEREage>20;

以上「>=」 (20歳以上であるとき)

SELECTname,ageFROMFamilyWHEREage>=20;

より小さい「<」 (20歳より小さいとき)

SELECTname,ageFROMFamilyWHEREage<20;

以下「<=」 (20歳以下であるとき)

SELECTname,ageFROMFamilyWHEREage<=20;

Case8:表から複数の条件を指定してデータを検索して、取得します。

実際の想定例・・・
サザエさんに登場するキャラのなかで、年齢が30歳に満たない男性を知りたくなったとき。

SELECTname,gender,ageFROMFamilyWHEREgender='男'ANDage<30;

Family表からgender列が「男」で、かつage列「30未満」であるname列とgender列とage列を取得します。

qiita_select_name_age_gender_where_age_30_gender_male.png

参考:
ほかの論理演算子の場合は以下のようになります。

「または」(男性もしくは、B型でない)

SELECTname,gender,bloodFROMFamilyWHEREgender='男'ORblood<>'B型';

「否定」(男性でない)

SELECTname,genderFROMFamilyWHERENOTgender='男';

Case9:Betweenで範囲を指定します。

実際の想定例・・・
サザエさんに登場するキャラのなかで、1900年から1910年の間に生まれたのは誰なのか気になったとき。

SELECTname,birthdayFROMFamilyWHEREbirthdayBETWEEN'1900-01-01'AND'1910-12-31';

Family表からbirthday列が「1900-01-01」から「1910-12-31」の間にあるname列とbirthday列を取得します。

もちろん以下の記法でも大丈夫です。

SELECTname,birthdayFROMFamilyWHEREbirthday>='1900-01-01'ANDbirthday<='1910-12-31';

qiita_select_name_birthday_between.png

Case10:複数の論理演算子を使用した場合の優先順位を確認します。6

実際の想定例・・・
サザエさんに登場するキャラのなかで、血液型が「不明」もしくは「A型」の女性が誰なのか、クイズで答える必要があるとき。

SELECTname,gender,bloodFROMFamilyWHERE(bloodISNULLORblood='A型')ANDgender='女';

Family表からblood列が「空白」もしくは「A型」で、かつgender列が「女」という条件のname列とgender列とblood列を取得します。

qiita_select_name_gender_blood_where_AND_OR.png

Case11:指定した文字列を含むデータを取得します。

実際の想定例・・・
サザエさんに登場するキャラのなかで、名前に「野」がつく人を知りたくなったとき。

SELECTnameFROMFamilyWHEREnameLIKE'%野%';

Family表からname列に「野」が含まれるname列を取得します。

qiita_select_name_like_wildcard.png

参考:
「%」は、ワイルドカードと呼ばれ「任意のデータの代用」をできます。%は文字数が不明なときに、利用できます。
ワイルドカードは、他に「」があります。文字数がわからない時は、「%」を、文字数がわかる時は、「」を使い分けることで、効率よくデータを取得できます。
例えば「磯野波平」を取得したい時は、4文字ということが分かっていれば、「%」よりも「_」を使う方が効率よく検索することができます。

SELECTnameFROMFamilyWHEREnameLIKE'_野__';

2. もっと細かく検索したい人向け!

より細かく検索ができるように、ビューという方法があります。

Case12:特定の条件で、表を分割して名前をつける。

実際の想定例・・・
サザエさんに登場するキャラを、磯野家という家族単位で管理したい。

CREATEVIEWIsonokeASSELECT*FROMFamilyWHEREnameLIKE'磯野%';

Family表からname列に「磯野」が含まれるという条件で、全ての列を取得して、「Isonoke」という名前をつけます。

qiita_create_isonoke.png

SazaesanというDBのなかに、「Family」というテーブルと「isonoke」というビューが作成されました。ビューは、大文字小文字を区別していないので、「Isonoke」で登録しても「isonoke」として登録されています。
ビューを作成することで、「磯野家」のなかで、検索するときには、いちいちWHERE句で条件を指定しなくても良い点があります。

ちなみに新規のテーブルを作らず、わざわざビューを使うメリットは、元々のFamilyのデータで変更があると、ビュー側でも変更されるからです。

もちろんフグ田家も作成できますよ!

3. データベースを作る方法

自らDBを作ることになることは、あまりないと思うので、DBの作り方は、簡単に紹介します。
需要があれば加筆修正いたします。

CREATEDATABASESazaesan;SHOWDATABASES;USESazaesan;

CREATE DATABASEで、データベースを作成します。
今回はSazaesanとします。
SHOW DATABASEで、現在どんなデータベースがあるのかを確認できます。
USE でどのデータベースを使うのかを指定します。
実際のデータベースを触る時は、基本的にUSEされた後の状態で使用することが多いと思います。

Column:
sqlは、アルファベットの大文字と小文字を区別しません。
なので、create database sazaesanもCREATE DATABASE SAZAESANも全て同じ命令ですが、入門書に書いてあった通りSQL命令を大文字表記、データベースや表の名前は先頭大文字表記、列名などは全て小文字表記として記述しています。

表を作って、データを入力します。

SHOWTABLES;CREATETABLEFamily(family_idCHAR(4)NOTNULL,nameVARCHAR(10)NOTNULL,genderCHAR(1)NOTNULL,birthdayDATENOTNULL,categoryVARCHAR(10)NOTNULL,category_idCHAR(4)NOTNULL,ageINT,bloodVARCHAR(3),PRIMARYKEY(family_id));

Column:
それぞれの列名と列のデータ型、空白を許すか否かを定義します。
データ型は、
整数型(INT)・・・小数点以下がない数値
実数型(DOUBLE)・・・小数点以下がある数値
固定長文字列型(CHAR)・・・固定された文字数の文字列
可変長文字列型(VARCHAR)・・・任意の文字数の文字列
日付型(DATE)・・・YYYY-MM-DD形式の日付
の5種類あります。
今回のテーブルでは、実数型を除く4種類を用いました。

Family表にデータを登録します。

INSERTINTOFamilyVALUES('F001','磯野波平','男','1895-09-14','office','C001',54,NULL);INSERTINTOFamilyVALUES('F002','磯野舟','女','1901-01-01','house','C002',48,NULL);INSERTINTOFamilyVALUES('F003','フグ田サザエ','女','1922-11-22','house','C002',27,'B型');INSERTINTOFamilyVALUES('F004','磯野カツオ','男','1938-01-01','school','C003',11,'B型');INSERTINTOFamilyVALUES('F005','磯野わかめ','女','1942-01-01','school','C003',7,'A型');INSERTINTOFamilyVALUES('F006','フグ田マスオ','男','1917-01-01','office','C001',32,'B型');INSERTINTOFamilyVALUES('F007','フグ田タラオ','男','1946-01-01','house','C002',3,NULL);

参考:
INSERT INTO テーブル名 VALUES();
今回の記事では説明していない、データをテーブルに追加するコマンドです。Family表には7つのデータを追加しています。

作成できたら、確認してみます。

SELECT*FROMFamily;

qiita_select_tables.png

アスタリスクは「指定しない」という意味です。
列名を指定すれば、その列だけを取得することも可能です。

まとめ

サザエさんの年齢と誕生日があまりにも古くて、改めて国民的アニメの長寿さに感動いたしました。さらに驚くべきことに、サザエさんとたらちゃんは未だに一度も声優が変わっていないそうです。この記事を期にというわけでもありませんが、サザエさんをまた見てみようと思いました。SQL関係ない

付録(Appendix)

情報元

参考にした書籍
https://ja.wikipedia.org/wiki/%E3%82%B5%E3%82%B6%E3%82%A8%E3%81%95%E3%82%93%E3%81%AE%E7%99%BB%E5%A0%B4%E4%BA%BA%E7%89%A9


  1. サザエさん一家に関してはwikipediaをはじめとしたネットメディアで調べた情報から構成しています。完全性も正確性も保証していないため、あくまでサンプルデータとしてご認識いただきたい。 

  2. 需要があれば、こちらの項目も書いていこうかなと思ったり思わなかったり・・・。 

  3. SQLの文法は同じだが、SHOW DATABASES;などの部分は異なる。実際にSQLのコマンドは、ほとんど同じだがあくまで「ほとんど同じ」なので、違う部分でエラー処理に悩んだ自分の経験からそもそも対象外としている。 

  4. 別にMacとWindowsの違いが、SQLに影響を及ぼすとは考えていないが、SQLのインストール系の話を飛ばしているため。 

  5. 本当にどうしても気になる時は、データベースなんかよりもGoogle検索をするなり「Hey Siri!」といって聞く方が確実であるが、そんなことは野暮だ。 

  6. 括弧をつけなくてもエラーが出るわけではないが、算術演算子(和算、減算、乗算、徐算)に優先順位があるように、論理演算子にも優先順位がある。「NOT > AND > OR」の順番で優先順位が高くなる。「NOT」の方が、「AND」よりも優先され、「AND」の方が、「OR」よりも優先される。予期しないエラーを出さないために、括弧で明示的に順序を決めておくほうが、スマートだ。 


Viewing all articles
Browse latest Browse all 21085

Trending Articles