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
の利用可否