はじめに
今回は自分が初めてSQLを勉強した時の備忘録になっています。
お付き合い頂ければ幸いです。
SQLとは
SQLとはデータベースを操作するときに使われる言語です。
特に、リレーショナルデータベース(RDB)を操作するときに使われます。
リレーショナルデータベース(RDB)について解説します。
リレーショナルデータベース(RDB)とは
データベースの内、関連のあるデータがまとめられているデータベースのことです。
どのようにデータがまとめられているかというと、データが表形式にまとめられています。
有名なOracle
やMySQL
はリレーショナルデータベースのひとつです。
RDBの構成
RDBはExcelのような表形式のデータになっています。
表のことをテーブル
といい、また縦の列のことをカラム
、横の列のことをレコード
と呼びます。
また、データベースに送る命令をクエリ
といいます。
SQLはそのクエリ
を書くための言語だということができます。
SQLのコマンド
それではSQLのコマンドについてまとめていきます。
SELECT、FROM
table1というテーブルからnumberというカラムを指定するときには以下のようにします。
SELECT number
FROM table1;
どこまでがクエリなのかを伝えるために、クエリの最後には;(セミコロン)を打ちます。
複数のカラムを指定したいときには以下のようにします。numberカラムとpriceカラムを指定しましょう。
SELECT number, price
FROM table1;
全てのカラムのデータを取得する場合は、greedy match(欲張りマッチ)である*を使いましょう。
SELECT *
FROM table1;
WHERE
WHEREを用いると、特定のデータを取得することができます。
WHERE カラム名=○○
とすることで、カラム名が○○であるデータを取得することができます。
以下のようにすると、table1テーブルのnameカラムが犬であるレコードを取得することができます。
SELECT *
FROM table1
WHERE name="犬";
データベースのデータ型には大きく分けて「数値型」「文字列型」「日付型」
が存在し、文字列型と日付型はダブルクォーテーションで囲む必要があります。データ型についてはこちらの記事を参考にしてください。
また、WHEREの後ろにNOTを用いると、NOTの後ろの条件を満たさないデータを取得できます。
SELECT *
FROM table1
WHERE NOT name="犬";
また、WHEREの後ろには比較演算子を用いて条件を指定することもできます。次のようにすれば、table1テーブルにおいてpriceカラムのデータが500以上のレコードを取得することができます。
SELECT *
FROM table1
WHERE price >= 500;
LIKE
また、WHEREの後にLIKE演算子を用いることで、「~のようなデータ」を取得することができます。
LIKE演算子は、どの文字列ともマッチするワイルドカードとともに使います。LIKE演算子は、「%」をワイルドカードとして扱います。
nameカラムのデータに「柴犬」「秋田犬」「土佐犬」のデータが含まれていて、この三つの「~犬」のデータを含むレコードを取得したい時は、以下のようにします。
SELECT *
FROM table1
WHERE name LIKE "%犬";
このワイルドカードを用いた文字列の指定は正規表現とほぼ同じなので、解説は省略します。
NULLについての取り扱い
データベースは完璧ではないため、「データが入っていないデータ」が存在します。
その「データが入っていないデータ」にはNULL
が入っています。
データが入っていないデータを指定するときに、=を用いても取得できません。
例えば、table1テーブルのnameカラムがNULLであるデータを取得するとき、以下のようにすると失敗します。
SELECT *
FROM name
WHERE name=NULL;
NULLを指定したい時はis NULL
やis NOT NULL
を使用するようにしましょう。
nameがNULLであるレコードを取得するときは以下のようにします。
SELECT *
FROM name
WHERE name is NULL;
nameがNULLでないレコードを取得するときは以下のようにします。
SELECT *
FEOM name
WHERE name is NOT NULL;
AND演算子とOR演算子
WHEREで複数の条件を指定するときは、AND演算子とOR演算子を使います。
ANDは~かつ~
のように条件を指定でき、ORは~または~
のように条件を指定できます。
nameが秋田犬かつ、priceが5000以上のレコードを取得するには以下のようにします。
SELECT *
FROM table1
WHERE name="秋田犬"
AND price >= 5000;
nameが秋田犬または土佐犬であるレコードを取得するには以下のようにします。
SELECT *
FROM table1
WHERE name="秋田犬"
OR name="土佐犬";
データの並べ替えについて
データを並べ替えるには、ORDER BY
を用いましょう。
昇順(小さい方から大きい方)に並べ替えたい場合はASC
を用いて、降順(大きい方から小さい方)に並べ替えたい場合はDESC
を用います。
ORDER BY カラム名 ASC
のような構文で使います。
table1テーブルのデータをpriceカラムについて昇順(ASC)に並べ替えたい場合は、以下のようにします。
SELECT *
FROM table1
ORDER BY price ASC;
必要な数だけデータを取得したいとき
データを取得する数を制限するときはLIMIT
を用います。
table1テーブルのデータをpriceカラムについて昇順(ASC)に並べ替え、最大10件を表示する場合は以下のようにします。
SELECT *
FROM table1
ORDER BY price ASC
LIMIT 10;
重複したデータの省き方
DISTINCT
を用いれば、検索結果から重複するデータを除くことができます。
使い方としてはDISTINCT(カラム名)
とすることで、指定したカラムに重複したデータが含まれる場合にそのレコードを除くことができます。
table1テーブルのnameカラムに重複する要素がある場合に、その重複要素を除去したい場合は以下のようにします。
SELECT DISTINCT(name)
FROM table1;
四則演算を使う
sqlでは、四則演算を行うことも可能です。
以下のようにすれば、priceカラムを1.10倍したデータを取得できます。
SELECT name, price*1.10
FROM table1;
数値の合計の取得
SUM関数
を用いることで、数値の合計を取得することができます。
以下のようにすると、table1テーブルのpriceカラムの豪渓を取得できます。
SELECT SUM(price)
FROM table1;
SUM関数はWHEREと併用することも可能です。
以下のようにすると、table1テーブルのnameカラムが「秋田犬」であるレコードのpriceの合計を取得できます。
SELECT SUM(price)
FROM table1
WHERE name="秋田犬";
数値の平均の取得
AVG関数
を用いることで、数値の平均を取得できます。
以下のようにすると、table1テーブルのnameカラムが「秋田犬」であるレコードのpriceの平均を取得できます。
SELECT AVG(price)
FROM table1
WHERE name="秋田犬";
データの数を計算する
データの数を計算するには、COUNT関数
を使います。
COUNT(カラム名)
という構文で用いれば、そのカラムに含まれるデータの合計が取得できますが、そのカラムにNULLがある場合はNULLを省いた合計を取得します。
単純にレコードの合計を取得したい場合はCOUNT(*)
としましょう。
以下のようにすれば、table1テーブルに含まれるレコードの合計を取得できます。
SELECT COUNT(*)
FROM table1;
また、以下のようにすればnameカラムが「秋田犬」であるレコードの数を取得できます。
SELECT COUNt(*)
FROM table1
WHERE name="秋田犬";
最大と最小のデータの取得
MAX関数
を使えば最大のデータを、MIN関数
を使えば最小のデータを取得できます。
以下のようにすれば、nameカラムが「秋田犬」であるレコードの中でpriceカラムが最小のもののpriceの値を取得できます。
SELECT MAX(price)
FROM table1
WHERE name="秋田犬";
グループ化について
GROUP BY
を用いると要素をグループ化することができます。
このグループ化の部分は少し複雑なので、詳しく見たい人はこちらの記事を参考にしてください。
GROUP BY カラム名
の構文で、「カラムに重複している要素」でグループ化することができます。
例えば、table1テーブルのnameカラムに「秋田犬」「土佐犬」「柴犬」の三要素のみが存在する場合を考えます。
この場合にGROUP BY name
とすると、「秋田犬」のグループと「土佐犬」のグループと「柴犬」のグループの三つのグループに分割されます。
この三つのグループに分割された状態で、もともとのpriceカラムにアクセスすることはできません。
なぜなら、三つのグループに分割された段階で、「グループに対するデータ」しか残っていないからです。
具体的には、「秋田犬」のグループの合計のpriceや、「土佐犬」のグループの要素の数の合計などのデータにしかアクセスできなくなります。
以下のように覚えてください。
GROUP BYを用いた場合にSELECTで使えるのは、GROUP BYで指定しているカラム名と、集計関数のみである。
集計関数(SUMやCOUNTなど)であるならば、そのグループに対してのデータにアクセスできますよね。
以下のようにすると、table1テーブルをnameカラムについてグループ化し、そのグループ化したデータについてのpriceの合計とグループ化したデータの数にアクセスできます。
SELECT name, SUM(price), COUNT(*)
FROM table1
GROUP BY name;
上のコードにより、グループ化されたnameカラムの、各々のグループに対するpriceカラムの値の合計と要素の合計をnameカラムのグループに対して表示することができます。
WHEREとGROUP BYを同時に使う場合
WHEREとGROUP BYを同時に使うと、先にWHEREで条件が絞られた後にGROUP BYでグループ化されます。
例えば以下のようにすると、table1テーブルでpriceが5000以上のデータに対して、nameカラムをグループ化した後にそのグループ化したデータに対してpriceの合計とデータの数を取得することができます。
SELECT name, SUM(price), COUNT(*)
FROM table1
WHERE price >= 5000
GROUP BY name;
グループ化したデータを絞り込むHAVINGについて
WHEREはグループ化する前に条件を絞り込むことができますが、HAVINGを用いるとグループ化した後に条件を絞り込むことができます。
FROM → WHERE → GROUPBY → HAVING → SELECT → ORDERBY
の順番にsqlのコマンドが実行されることを覚えておきましょう。
WHEREとHAVINGの違いについてはこちらの記事に良くまとめられていたので、参考にしてください。
HAVINGはグループ化した後のデータに対して用いるため、HAVINGの後の条件に指定できるのはGROUP BYで指定しているカラム名と、集計関数のみである
という点に注意してください。
以下のようにすると、table1テーブルのデータをnameカラムについてグループ化した後に、そのグループ化したデータのpriceの合計が50000以上のデータを取得できます。
SELECT name, SUM(price)
FROM table1
GROUP BY name
HAVING SUM(price)>=50000;
終わりに
今回はここまでになります。ここまでお付き合い頂きありがとうございました。