SQLの基本1(SELECT)

SQLってどんなもの?

前回データベースとはどういうものかというご説明をいたしました。

今回はそのデータベースを利用するためのSQL(Structured Query Language)についてご説明します。

テーブルとは

テーブルとはエクセルのシートのようなものとご説明しました。
実際にイメージで見てみると下の表のようになります。

シート名「従業員」がテーブル名で、1行目の「従業員No」や「従業員名」「役職」「上長」「入社日」「給与」「部署No」が列名(カラム)と呼ばれるものです。

テーブルの構造は基本的に「主キー」と呼ばれるユニーク(列の中で一意)な値を持つ列が存在します。
このテーブルの場合「従業員No」が主キー(Primary Key)になります。

また、リレーショナルデータベースでは別のテーブルと結合して値を抽出することができます。
一般的には自身のテーブルに存在する外部キー(Foreign Key)と結合したいテーブルの主キー(Primary Key)を接続して抽出します。
上記のテーブルの外部キーは「部署No」となります。
下記に結合するテーブルを記載します。

上記テーブルの主キーは「部署No」となります。

では、上記の2つのテーブルを使って説明していきます。

SELECT文(任意のデータを抽出する)

SELECT 列(カラム)名 FROM テーブル名 WHERE 抽出条件

まず1つのテーブルでデータを抽出してみましょう。
では、従業員テーブルから入社日が2018/1/1以降の人を抽出してみましょう。

SELECT 従業員名, 役職, 入社日
FROM 従業員
WHERE 入社日 >= 2018/1/1

となります。
SELECTの後に抽出したいカラム名、FROMの後に抽出したいテーブル名、WHEREの後に条件を記載します。

下図はEXCELのフィルタを使って表示しましたが、検索結果としては下図のように6レコードが抽出されます。
※実際にはB列C列E列のみが表示されます。

★Tips★ *で抽出カラム名の記載を省略する

SELECT *
FROM 従業員
WHERE 入社日 >= 2018/1/1
上記のように記載すると、そのテーブルに含まれるすべての列が抽出されます。
ちょっと一覧を出して確認したい時や副問い合わせ(後にご説明します)の時に便利です。

また、抽出条件は and や or を使って複数記載出来ます。

SELECT 従業員名, 役職, 入社日
FROM 従業員
WHERE 入社日 >= 2018/1/1 and 給与>= 270000

とすると、入社日が2018/1/1以降で給与が270000以上の人を抽出できます。
森さんと田口さんの2レコードが抽出されます。
※実際にはB列C列E列のみが表示されます。

SELECT文(テーブルを結合する)Inner Join、Outer Join

では、2つのテーブルを結合してみましょう。

テーブルの結合の仕方については、Inner Join~(内部結合)やOuter Join~(外部結合)のような色々な書き方がありますが、まずは簡単なOracle形式でご説明します。

Inner Join(内部結合)とは
 テーブル同士を結合した結果、両方のテーブルに存在するものだけを抽出する。

Outer Join(外部結合)とは
 テーブル同士を結合した結果、片方のテーブルの内容は全て表示し、もう一方のテーブルの内容は一致したものだけを抽出する。

Inner Join
では、従業員テーブルと部署テーブルをInner Joinで結合してみましょう。

SELECT 従業員.従業員名, 従業員.役職, 従業員.入社日, 部署.部署名
FROM 従業員, 部署
WHERE 従業員.部署No = 部署.部署No
※この接続方法がInner Joinです。

このようにすると下図のように抽出されます。
※実際にはB列C列E列H列のみが表示されます。

H列のところに部署名が抽出されました。

複数のテーブルを結合した場合、SELECT句にカラム名を記載するときはテーブル名を先頭に付けて度のテーブルのどのカラムであるかを明示する必要があります。

FROM句には抽出したいテーブル名を記載します。
この場合、従業員テーブルと部署テーブルの2つをカンマで区切って記載。

WHERE句にはテーブル同士の結合条件を記載します。
この場合、従業員テーブルの外部キー(部署No)と部署テーブルの主キー(部署No)を=で結合します。
※先ほどのように従業員.入社日 >= 2018/1/1 and 従業員.部署No = 部署.部署Noとして入社日を2018/1/1以降の人の部署を表示させることもできます。

ちなみに、テーブル名には別名を付けることができます。
SELECT A.従業員名, A.役職, A.入社日, B.部署名
FROM 従業員 (AS) A, 部署 (AS) B
WHERE A.部署No = B.部署No
※ASは省略可能です。

このように別名を付けると、たくさんテーブル名を記載しないといけない場合に楽になります。


Outer Join
次にOuter Joinについてご説明します。

SELECT 従業員.従業員名, 従業員.役職, 従業員.入社日, 部署.部署名
FROM 従業員, 部署
WHERE 従業員.部署No = 部署.部署No(+)
※この接続方法がOuter Joinです。

WHERE句に(+)を付けると従業員テーブルのすべてを表示しつつ、部署テーブルの部署Noが一致したものだけ部署名を表示します。
8行目の高橋社長は部署Noが50なので部署テーブルには50のデータが存在しないため空欄となっています。

SELECT文(副問い合わせ)

副問い合わせとはFROM句やWHERE句にテーブル名や単一条件を指定する代わりに、SELECT文を記載して抽出した結果のテーブルを再検索することができます。

ちょっと分かり辛いと思うので、実際のSQL分を例にご説明します。

例えば従業員テーブルの従業員に対して上長は誰かを表示するSQL分を記載してみましょう。

SELECT A.*, B.上長名
FROM 従業員 A, (SELECT 従業員No AS 上長No, 従業員名 AS 上長名 FROM 従業員 WHERE 部署No != 50) B
WHERE A.上長 = B.上長No(+)
※!=は<>と同じ意味でイコールではないという意味です。

この例ではFROM句に社長の部署Noを除くそれ以外の一覧をテーブルとして見立ててそのテーブルを元のテーブルに結合しています。
※同じテーブルで問い合わせを行っていることから抽出されるカラム名に別名を付けてわかりやすくしています。

抽出すると下図のような一覧が表示されます。

例えば平均以上の給与をもらっている人の一覧を出してみましょう。
この場合はWHERE句に副問い合わせを記載する方が楽です。

SELECT *
FROM 従業員
WHERE 給与 > (SELECT AVG(給与) FROM 従業員)
※AVGは集計関数と言って平均を求めるものです。EXCELの関数でも出てきましたね。

全員の平均の金額は334000円ですので、それ以上の人が一覧で表示されます。

いかがでしたか?

今回は基本的なSELECT文についてご紹介しました。
SELECT文には集計関数も使えますので、次回は集計の方法について詳しく見ていきましょう。

では、次回をお楽しみに。