SQLとは
SQLとは、データベースを操作(ローカルへのデータ取得やDBへのデータ追加等々)するためのプログラミング言語。本記事ではデータ取得機能(SELECT文)のみを説明する。
使用場面
SQLを使用するのは以下のようなケース:
- システムのDBからデータを取得する場合
- 条件を指定した抽出
- 簡単な計算(単位を変える等)
逆に以下のようなケースでは使用しない方がよい:
- 複雑な変形・計算 -> より簡単にできるPandasやPower Queryで
SELECT文の基本構造
国別年月別の売上高をデータとする「売上」というテーブルがDBにあるとする:
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/6 | 32 |
| 日向 | 21/7 | 33 |
そこから薩摩と大隅のデータを取得するには次のようなSQL文となる:
SELECT
国, 年月, 売上 #`FROM`句で指定したテーブルに含まれる列のうち、使用する列を選択
FROM
売上 #データ元テーブル
WHERE
国 IN ("薩摩", "大隅") #(省略可)抽出条件
ORDER BY
売上 #(省略可)並べ替え順序
;
以下、このSQL文の各要素を説明する。
列選択
SELECT文の直後に記載。後述のFROM句で取得したテーブルからどの列を取得するかを指定する部分。
基本
-
すべての列を選択する場合は
*(アスタリスク)。 -
特定の列を選択するには、列名を
,(カンマ)で区切って記載。 -
別名で使用したい場合は次のように、列名の後にスペースを空けて指定する:
SELECT 国 country, 年月 YYMM, 売上 #DBによっては 年 AS yのようにASが使える FROM 売上 ; -
列単位で計算が可能→Link
SELECT 売上 / POWER(10, 3) AS 売上_千円 FROM 売上 ;
応用
-
関数を利用できる。
TO_DATE関数の例:# 約定日テーブルにあるtrading_date列(YYYYMMDDの数字8桁)を日付形式に変換して取得する SELECT TO_DATE(trading_date) AS 約定日 FROM 約定テーブル ; -
DISTINCT句で重複を削除SELECT DISTINCT 魚種 fish FROM 漁獲テーブル ;
WHERE句
以下で紹介する様々な比較演算子の結果を、論理演算子(AND, OR, NOT等)と括弧((、))を組み合わせて、抽出条件を指定する。
比較演算子(基本)
| 比較演算子 | 機能 | 使用例 |
|---|---|---|
| = | A と B は等しい | A = B |
| <=> | A と B は等しい ※NULL可 | A <=> B |
| <> | A と B は等しくない | A <> B |
| != | A と B は等しくない | A != B |
| < | A は B よりも小さい | A < B |
| <= | A は B 以下 | A <= B |
| > | A は B よりも大きい | A > B |
| >= | A は B 以上 | A >= B |
比較演算子(応用)
| 比較演算子 | 機能 | 使用例 |
|---|---|---|
| IS [NOT] | A は Bである | ○ IS B |
| IS [NOT] NULL | A は NULLである | A IS NULL |
| [NOT] BETWEEN AND | A は min以上max以下 | A BETWEEN min AND max |
| [NOT] IN | A は 括弧内のいずれかの値に等しい | A IN (B, C, …) |
| ANY | A は 括弧内のいずれかの値に等しい | A ANY (B, C, …) |
| [NOT] LIKE | 正規表現を使用した文字列検索 | A LIKE B |
| [NOT] REGEXP | 正規表現を使用した文字列検索 | A REGEXP B |
| [NOT] RLIKE | REGEXPと同じ | A EGEXP B |
FROM句
どのテーブルを取得するかを指定する。複数のテーブルの場合はJOIN句で結合する。
基本
- 元になるテーブルを指定。
- 別名で使用したい場合は
SELECTと同様、列名の後にスペースを空けて指定する。
応用
複数のテーブルの結合が可能。JOIN句での結合が必要になるが、ここではよく使う内部結合と左外部結合を説明する。
内部結合
二つのテーブルの結合条件が一致したレコードを取得する。片方のテーブルのみにしかデータが無い場合には含まれない:
売上テーブル
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/6 | 32 |
| 日向 | 21/7 | 33 |
四半期テーブル
| 年月 | 四半期 |
|---|---|
| 21/5 | 1Q |
| 21/6 | 1Q |
↓ 内部結合
| 国 | 年月 | 売上 | 四半期 |
|---|---|---|---|
| 薩摩 | 21/6 | 12 | 1Q |
| 大隅 | 21/6 | 22 | 1Q |
| 日向 | 21/6 | 32 | 1Q |
SQLの記載方法:
SELECT
国, 年月, 売上, 四半期
FROM
売上 INNER JOIN 四半期
ON 売上.年月 = 四半期.年月
;
左外部結合
最初のテーブルの全レコードおよび二つのテーブルの結合条件が一致したレコードを取得する:
売上テーブル
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/6 | 32 |
| 日向 | 21/7 | 33 |
四半期テーブル
| 年月 | 四半期 |
|---|---|
| 21/5 | 1Q |
| 21/6 | 1Q |
↓ 左外部結合
| 国 | 年月 | 売上 | 四半期 |
|---|---|---|---|
| 薩摩 | 21/6 | 12 | 1Q |
| 薩摩 | 21/7 | 13 | null |
| 大隅 | 21/6 | 22 | 1Q |
| 大隅 | 21/7 | 23 | null |
| 日向 | 21/6 | 32 | 1Q |
| 日向 | 21/7 | 33 | null |
SQLの記載方法:
SELECT
国, 年月, 売上, 四半期
FROM
売上 LEFT OUTER JOIN 四半期
ON 売上.年月 = 四半期.年月
;
ORDER BY句
- 並べ替えのキーを指定(昇順)
- 降順にするには、
列名 DESC - 複数キーで並べ替えるには、
,(カンマ)で区切る
ネストしたSELECT文
SELECT文の中で入れ子でSELECT文を呼び出すことが可能。入れ子状のSELECT文のことを、「ネストしたSELECT文」、「副問い合わせ」等という。
FROM区内のSELECT文
(後日追記)
WHERE区内のSELECT文
以下のテーブルで、四半期の値が2Qのものだけ取り出したい場合
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/6 | 32 |
| 日向 | 21/7 | 33 |
四半期テーブル
| 年月 | 四半期 |
|---|---|
| 21/5 | 1Q |
| 21/6 | 1Q |
| 21/7 | 2Q |
↓ 四半期の値が2Qのものだけ取り出す
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/7 | 33 |
ネストしない場合は、結合した上でWHEREで指定する:
SELECT
国, 年月, 売上
FROM
売上 LEFT OUTER JOIN 四半期
ON 売上.年月 = 四半期.年月
WHERE
四半期.四半期 = "2Q"
;
ネストする場合は、結合が不要:
SELECT
国, 年月, 売上
FROM
売上
WHERE
年月 IN (
SELECT
年月
FROM
四半期
WHERE
四半期 = "2Q"
)
;
どちらかでしかできないことがあればそれを使い、そうでなければ読みやすい方を使えばよい。
UNION文による統合
UNIONまたはUNION ALL文を使えば、2つのSELECT文の結果を統合(=行を追加)できる。
売上1テーブル
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
売上2テーブル
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
↓UNIONまたはUNION ALL
| 国 | 年月 | 売上 |
|---|---|---|
| 薩摩 | 21/6 | 12 |
| 薩摩 | 21/7 | 13 |
| 大隅 | 21/6 | 22 |
| 大隅 | 21/7 | 23 |
| 日向 | 21/6 | 32 |
| 日向 | 21/7 | 33 |
上記のSQL文は以下のとおり:
SELECT
国, 年月, 売上
FROM
売上1
UNION #またはUNION ALL
SELECT
国, 年月, 売上
FROM
売上2
;
制約:
- 2つの
SELECT文の結果の列数が同じでなければ使用不可 - 2つの
SELECT文の結果の各列の型が同じか、2つめのSELECT文の結果の各列が1つめのSELECT文の結果の各列に変換可能でなければ使用不可 - 列名は1つめの
SELECT文の結果のものが使われる
UNIONとUINION ALLの違い:
-
UNION: 統合したデータ内に重複があれば削除。レコード数が多い場合、サーバーへの負荷が大きい。 -
UNION ALL: 統合したデータ内に重複があっても削除しない。
その他
SQLはDBに依って記述方法が微妙に異なることがある。例えば、
-
;(セミコロン)の要否。とりあえず付けておけば問題ない。 -
ASの利用可否