SQL初心者が、勉強しながら覚書としてまとめた記事です。
基本の理解
テキストや数値などのデータを保存するためのツールである「データベース」は、「テーブル(表)」でデータを管理しており、縦の列のことを「カラム」、横の行のことを「レコード」と呼ぶ。
データベースからデータを取得するためには、命令(クエリ)を送る。
SQLは、その命令(クエリ)を書くための言語。
SQLの基本的な書き方
- コメント...
--
に続けて書く
データベースからデータを取得する
-
SELECT
...どのカラムのデータを取得するかを指定(全ての場合は*
) -
FROM
...どのテーブルのカラムから取得するかを指定
SELECT カラム名1, カラム名2
FROM テーブル名;
※SQLは大文字と小文字を区別しない。
特定のデータを取得する(WHERE)
WHERE
で、どこのレコードからデータを取得するかを指定する。
SELECT *
FROM テーブル名
WHERE カラム名 = "値";
※数値は""で囲わないが、日付は囲う必要がある。
比較演算子を使う
SQLでは、比較演算子を利用して取り出すデータを指定することができる。
書き方の例。purchasesテーブルから、priceカラムが1000円以上のデータを取得する。
SELECT *
FROM purchases
WHERE price >=1000;
ある文字を含むデータを指定する(LIKE演算子)
-
LIKE
を使うことで、指定したカラムがある値のデータを持つレコードからデータを取得することができる。 -
%文字列%
(ワイルドカード)...指定した文字列を含む全てのデータ -
文字列%
(前方一致)...指定した文字列から始まるデータ -
%文字列
(後方一致)...指定した文字列で終わるデータ
書き方の例。nameカラムに「プリン」を含むデータを全て取得する。
SELECT *
FROM purchases
WHERE name LIKE "%プリン%";
NOT演算子を使う
WHEREの後に NOT
をつけると、「〇〇を含まないデータ」や「〇〇に一致しないデータ」のような条件になる。
書き方の例。priceカラムが1000円以上“でない”データを取得する。
SELECT *
FROM purchases
WHERE NOT price >=1000;
空のデータを取得する(NULL)
-
IS NULL
...カラムが空のレコードからデータを取得 -
IS NOT NULL
...カラムが空でないレコードからデータを取得
書き方の例。priceカラムが空でないデータを取得する。
SELECT *
FROM purchases
WHERE price IS NOT NULL;
複数の条件で指定する(AND演算子・OR演算子)
以下を使って、WHEREに複数の条件を指定することができる。
-
AND
...複数の条件すべてを満たすデータを取得 -
OR
...複数の条件のいずれかを満たすデータを取得
書き方の例。カテゴリーが"食費"で、かつ、character_nameが"猫"のデータを取得する。
SELECT *
FROM purchases
WHERE category="食費" AND character_name="猫";
データを並び替える(ORDER BY)
ORDER BY
をクエリの末尾に記述することで、データの取得結果を並び替えることができる。
-
ASC
...昇順 -
DESC
...降順
ORDER BY 並べ替えたいカラム名 並べ方;
書き方の例。character_nameが"猫"のデータを取得し、priceカラムを基準に昇順に並べ替える。
SELECT *
FROM purchases
WHERE character_name = "猫"
ORDER BY price ASC;
取得するデータの件数を制限する(LIMIT)
LIMIT
をクエリの末尾に記述することで、最大で何件取得するかを指定することができます。
LIMIT データの件数;
書き方の例。character_nameが"猫"のデータをpriceを降順に並べ替えた上で、5件目までを取得する。
SELECT *
FROM purchases
WHERE character_name = "猫"
ORDER BY price DESC
LIMIT 5;
検索結果を加工する
重複したデータを省く(DISTINCT)
DISTINCT(カラム名)
で、検索結果から指定したカラムの重複するデータを除くことができる。
書き方の例。重複を除いた状態でnameカラムのデータを取得する。
SELECT DISTINCT(name)
FROM purchases;
四則演算を使う
SQLでは、+(足す), -(引く), *(掛ける), /(割る)を使って、取得したデータを加工することができる。
書き方の例。nameカラムとpriceカラムのデータを取得し、priceは消費税込みの金額にする。
SELECT name, price * 1.08
FROM purchases;
合計を計算する(SUM)
SUM(カラム名)
を使って、取得したデータの合計を求めることができる。
書き方の例。character_nameが"猫"のpriceデータを取得して合計を求める。
SELECT SUM(price)
FROM purchases
WHERE character_name = "猫"
;
平均を計算する(AVG)
AVG(カラム名)
を使って、取得したデータの平均を求めることができる。
書き方の例。character_nameが"猫"のpriceデータを取得して平均を求める。
SELECT AVG(price)
FROM purchases
WHERE character_name = "猫"
;
データの数を求める(COUNT)
COUNT(カラム名)
を使って、データの数を求めることができる。
nullの数も含めてレコードの数を計算したい場合は、COUNT(*)
とする。
※そのままだとnullのデータの数は計算されない。
書き方の例。character_nameが"猫"のpriceデータの数(nullを含む)を求める。
SELECT COUNT(*)
FROM purchases
WHERE character_name = "猫"
;
最大・最小を求める(MAX・MIN)
MAX(カラム名)
や MIN(カラム名)
を使って、データの最大値、最小値を求めることができる。
書き方の例。character_nameが"猫"のpriceデータの最大値を求める。
SELECT MAX(price)
FROM purchases
WHERE character_name = "猫"
;
グループ化する(GROUP BY)
FROMの後ろに GROUP BY カラム名
を追記すると、指定したカラムで同一のデータを持つレコードがグループとなり、集計関数により、各グループごとにデータが集計される。
※GROUP BYを使う場合、SELECTで使えるのは、GROUP BYに指定しているカラム名と、集計関数のみ。
書き方の例。purchased_atでグループ化し、買い物をした日付ごとにお金を使った回数を取得する。
SELECT COUNT(price), purchased_at
FROM purchases
GROUP BY purchased_at
;
複数のカラムを使ってグループ化する(GROUP BY)
GROUP BY
の後カンマ(,)を挟んで複数のカラム名を入れることで、複数のカラムを使ってグループ化することができる。
書き方の例。purchased_atとcharacter_nameでグループ化し、日付とキャラクターごとに使ったお金の合計額を取得する。
SELECT SUM(price), purchased_at, character_name
FROM purchases
GROUP BY purchased_at, character_name
;
細かい条件でグループ化する
GROUP BY
と WHERE
を併用し、さらに細かい条件でグループ化することができる。
※GROUP BY
は WHERE
の後に書く。
書き方の例。categoryが"食費"であるデータを取得した上で、purchased_atとcharacter_nameでグループ化し、日付とキャラクターごとに使ったお金の合計額を取得する。
SELECT SUM(price), purchased_at, character_name
FROM purchases
WHERE category = "食費"
GROUP BY purchased_at, character_name
;
グループ化したデータを更に絞り込む(HAVING)
GROUP BY
でグループ化したデータから、更に特定のグループのみを取得する場合は HAVING
を使う。
WHERE
はグループ化される前のテーブル全体を検索対象とするのに対し、HAVING
は GROUP BY
によってグループ化されたデータを検索対象とする。
GROUP BY カラム名
HAVING 条件;
書き方の例。purchased_at(日付)でグループ化し、priceの合計額が2000円を超えるデータの合計額と日付を取得する。
SELECT SUM(price), purchased_at
FROM purchases
GROUP BY purchased_at
HAVING SUM(price) > 2000
;
サブクエリを使う
SQLでは、クエリの中に他のクエリを入れることができ、この他のクエリをサブクエリと言う。
2つ以上のクエリを1つにまとめることができるので、より複雑なデータを取得する際に使われる。
サブクエリの書き方
( )
で囲むことで、サブクエリを使用する。
※()内にはセミコロン(;)は不要。
書き方の例。平均得点数を出し、それより得点数が多い選手名と得点数を取得する。
SELECT name,goals
FROM players
WHERE goals > (
SELECT AVG(goals)
FROM players
);
カラム名に別名を定義する(AS)
AS
を使うことでカラム名などに別名を定義し、取得したデータが何なのかをわかりやすくすることができる。
カラム名 AS "名前"
書き方の例。チームの合計得点数を取得し、カラム名を"チームの合計得点"とする。
SELECT SUM(goals) AS "チームの合計得点"
FROM players
;
複数のテーブルを活用する
複数のテーブルを一緒に使うためには、「主キー」・「外部キー」が設定されたカラムを用意する必要がある。
テーブルの結合(JOIN)
紐付いたテーブル同士は JOIN
を使うことで合体させることができる。
結合したテーブルは1つのテーブルと同じようにデータを取得することができる。
SELECT *
FROM テーブルA
JOIN テーブルB
ON テーブルA.カラム名 = テーブルB.カラム名;
書き方の例。playerテーブルにcountriesテーブルを結合し、playerテーブルのcountry_idカラムとcountriesテーブルのidカラムを紐付ける。
SELECT *
FROM players
JOIN countries
ON players.country_id = countries.id;
複数テーブルでのカラムの指定
複数のテーブルに同じカラム名が存在するときは、テーブル名.カラム名
で指定する。
書き方の例。playerテーブルにcountriesテーブルを結合し、playersテーブルのnameカラムとcountriesテーブルのnameカラムを取得する。
SELECT players.name, countries.name
FROM players
JOIN countries
ON players.country_id = countries.id
;
NULLを含めて取得(LEFT JOIN)
JOINは外部キーがNULLであるレコードを取得しないが、LEFT JOIN
を使うことにより、NULLのレコードも実行結果に表示できる。
(NULLの部分は空白となって表示される)
書き方の例。playerテーブルにteamsテーブルを結合し、NULLも含めたデータを取得する。
SELECT players.name AS "選手名", teams.name AS "前年所属していたチーム"
FROM players
LEFT JOIN teams
ON players.previous_team_id = teams.id
;
3つ以上のテーブルを結合する
JOINを複数回使うことで、3つ以上のテーブルを結合することができる。
書き方の例。playerテーブルにcountriesテーブルとteamsテーブルを結合し、データを取得する。
SELECT *
FROM players
JOIN countries
ON players.country_id = countries.id
LEFT JOIN teams
ON players.previous_team_id = teams.id
;
実行される順序
上から順に実行される。
- テーブルの指定(FROM)
- 結合(ON, JOIN)
- 取得条件(WHERE)
- グループ化(GOUP BY)
- 関数(COUNT, SUM, AVG, MIN)
- HAVING(HAVING)
- 検索(SELECT, DISTINCT)
- 順序(ORDER BY)
- LIMIT(LIMIT)
最後に
2億年前にProgateで基礎だけやって止まっていたのですが、この記事↓を読んで勉強再開する気がおきました。ありがとうございます。