見出し画像

Pythonによるデータ解析を一通りやっている人向けのSQLチートシート

 こんにちは、WINUです。名前の読み方は「ウィヌ」となっております。今回はpythonでのデータ分析を既に行ったよーという方(numpyやpandas)に向けたデータベース言語の一つであるSQLのチートシートです。

 最近のデータサイエンス界隈はpythonによるデータ分析が主流となってきています。ただ、実際にデータサイエンティストの方と話をしているとまだまだSQLも現役との事。実際データベースに直接作用できるという点が点数高いですからね。それに、interviewでも出てくるという事で避けては通れません。

 そこで、つい先日SQLの基礎だけでも身に着けておこうと思い勉強した所、めちゃくちゃ簡単な事にびっくりしました。少しクセがあるものの、pythonによるデータ分析の知識を適用するとスラスラできる感じでした。

 そのため、この記事ではnumpyやpandasの知識を多く活用します。もし純粋にSQLを学びたい方は他のソースでの勉強をおススメします。それでは、早速チートシートに入りたいと思います。

基礎知識と用語

用語

リレーショナルデータベース:一つ、又は複数のデータをテーブル形式で保存するデータベース。DataFrame型のデータを一つから複数まで保存するデータベース。

テーブル:データ形式の一つ。それぞれのデータを示す行とカテゴリーを示す列によって構成されている。DataFrame型のデータの事。

クエリ(query):データベースに対する質問。SQL(Structured Query Language)によって書かれたクエリの「答え」に当たるデータをデータベースから引っ張ってきてもらう事がゴール。

例)「このテーブル内には合計でどれぐらいのデータがあるの?」というクエリを書くとテーブル内の行数を返す。

クローズ(Clause):データベースにおける操作を担うキーワード群。ケースはどちらでもいいが、基本的には大文字という事になっている。functionやmethodに近い。

基本的なクローズとクエリの基礎知識

FROM - テーブルの指定。どのテーブルを操作するかを宣言する。

WHERE - 条件の指定。演算子で条件を定義するときに使われる。

演算子(AND, OR)- 通常の演算子。pythonのAND / ORと同じ効力を持つ。

= - 基本的に代入も同値か否かの比較も=に統一されている。その代わり、それらを差別化するためのクローズが存在する。

; - クエリの最後はセミコロン(;)によって締めくくられる。これは質問文の結びである、はてなマークと同じ役割がある。

ダブルダッシュ(--)はコメント。pythonでは#。


Manipulation / 基本操作

CREATE TABLE - テーブルを作る。pandasでのpd.DataFrameによるテーブルデータの作成と同じもの。内容は「column_name dtype (optional_args),」という形で列の定義を行う。

CREATE TABLE テーブル名 (
    カラム名 データ型 オプション, 
    ...
); 

INSERT INTO - データの追加。pandasではappendやconcatにあたるもの。どちらの方法でも書けるが、カラム全てにデータを入れるのであれば、最初の方法を推奨。

INSERT INTO テーブル名
VALUES (データ1, データ2, ...); 

-- with specifying columns 
INSERT INTO テーブル名 (カラム1, カラム2)
VALUES (データ1, データ2);

SELECT - データの選択。カラムを選択してデータを得る。*は全てのデータを取ってくるという意味。DataFrameで格納してある変数を呼び出す事か、リストや辞書のようにカラム名を指定する事と同値。

-- select all data from specified table 
SELECT * FROM テーブル名;

-- select specific column from table 
SELECT カラム, ... FROM テーブル名;

ALTER TABLE - テーブルに変化を加える。カラムを増やす、データ型を変えるなどの操作を宣言後に定義する事で可能とする(下記の例はカラムの追加)。そのため、ALTER TABLE自体はテーブルの指定に使われる。

ALTER TABLE テーブル名

--option comes after (adding column this time)
ADD カラム名 データ型; 

UPDATE - テーブル内のデータの変更。UPDATEによりテーブル名を宣言、SETでどのカラムに何の値を入れるのかを定義し、WHEREで条件の宣言。df[df[col]==value] = ...と非常に似た事をやっている。

UPDATE テーブル名
SET カラム名1 = データ1, カラム名2 = データ2
WHERE カラム名 = データ; 

DELETE FROM - テーブル内のデータ削除を行う。WHEREで削除する対象となるデータの条件を宣言する。pandasのdropと同じ。

DELETE FROM テーブル名

-- specify condition 
WHERE カラム名 = データ; 


Queries / 細かいクエリ操作

AS - カラム名の更新。pandasのrenameメソッドがこれに値する。

SELECT カラム名 AS 新カラム名
FROM テーブル名; 

%, _ Wildcard - LIKEと併用する事でキーワード検索をかける。%はキーワードを前後(又は中間)に持つデータを検索し、_は逆にキーワードの中で欠けている部分を作り、その条件に合うデータを検索する。pandasではstartwithやendwith等で再現可能。

SELECT カラム名
FROM テーブル名
WHERE カラム名 LIKE '%ワード%';

SELECT カラム名
FROM テーブル名
WHERE カラム名 LIKE 'ワ_ド';

ORDER BY - テーブルのソート。ASCで昇順、DESCで降順。np.sort等と同じ機能。別途定義している。

-- sort by ascending order 
SELECT *
FROM テーブル名
ORDER BY カラム名 ASC;

-- sort by descending order 
SELECT *
FROM テーブル名
ORDER BY カラム名 DESC;

DISTINCT - ユニークな(重複のない)値を返す。pd.Series.unique()と同じ働きをする。

SELECT DISTINCT カラム名
FROM テーブル名; 

BETWEEN - 任意の値の範囲に存在するデータを返す。X以上Y以下等の条件を書くことが出来る。

SELECT *
FROM テーブル名
WHERE カラム名 BETWEEN 条件1 AND 条件2;

LIMIT - 返り値であるテーブルの行数を制限する。続く数字が行数となる。pd.DataFrame.head()メソッドと同じ機能。

SELECT *
FROM テーブル名
LIMIT 行数; 

NULL - データ値がない状態。pythonのNull、numpyのnp.nanと同じ。

SELECT *
FROM テーブル名
-- IS NOT / IS works in same way as python 'is' do
WHERE カラム名 IS NOT NULL;

CASE - if/elseの宣言。CASEとENDで囲った部分にWHEREとELSEクローズで条件と返り値を羅列する。なお、基本的には既存のカラムのデータから新しいカラムを作り出す際の条件となる。

SELECT カラム名, 
	CASE 
		WHERE 条件1 THEN 返り値1
		WHERE 条件2 THEN 返り値2
		ELSE 返り値3
	END
FROM テーブル名; 


Aggregate / 集計

SUM - 合計の計算。np.sum等と同じ。 

SELECT SUM(カラム名)
FROM テーブル名; 

MAX / MIN - 最大・最小値を返す。np.maximum / np.minimum等と同じ。

-- maximum 
SELECT MAX(カラム名)
FROM テーブル名; 

-- minimum
SELECT MIN(カラム名)
FROM テーブル名; 

COUNT - 行数の合計を計算。len()やpd.DataFrame.shape[0]等と同じ。

SELECT COUNT(*)
FROM テーブル名; 

GROUP BY - データをカテゴリー / 範囲ごとにまとめて集計する。pd.DataFrame.groupby(col)と同じ。以下の例ではそれぞれの範囲内のデータ数を集計している。

SELECT カラム名, COUNT(*)
FROM テーブル名
GROUP BY カラム名; 

AVG - 指定されたデータの平均値を計算。np.mean等と同じ。

SELECT カラム1, AVG(カラム2)
FROM テーブル名
GROUP BY カラム1;

HAVING - WHEREと基本的には同じ働きをするが、既にGROUP BYで集計されたデータに対して使われる。以下の例ではカラム1でまとめられたデータのデータ数が数値よりも大きい物のみを残す。

SELECT カラム1, COUNT(*)
FROM テーブル名
GROUP BY カラム1
HAVING COUNT(*) > 数値;

ROUND - 四捨五入。np.round等と同じ。二つの引数を取り、一つ目は対象のカラム、もう一つは小数点第何位までに納めるかを指定。

SELECT カラム1, ROUND(カラム2, 数値)
FROM テーブル名;


Multiple Tables / 複数テーブルの操作

Inner JOIN - テーブルの内部結合。両テーブルに存在するデータのみで結合する。テーブル名.カラム名とする事で、どのテーブルのどのカラムで結合するかを選択する。pd.merge()でhow='inner'とするのと同じ。

FROM テーブル1
JOIN テーブル2
	ON テーブル1.カラム1 = テーブル2.カラム2; 

Outer (LEFT) JOIN - テーブルの外部結合。シンタックスはLEFTとつける以外は通常のJOINと同じ。pd.merge()でhow='left'とするのと同じ。

SELECT *
FROM テーブル1
LEFT JOIN テーブル2
	ON テーブル1.カラム1 = テーブル2.カラム2; 

WITH - エイリアスを使って仮のテーブルを作る。元のデータを変えたくない場合に使われる。pd.DataFrame.copy()と同義。

WITH 仮テーブル名 AS (
    SELECT *
    FROM テーブル名
)
SELECT *
FROM 仮テーブル名
WHERE 条件;

UNION - 異なるテーブルの同じ種類のデータを重複なく一つのデータへと結合する。pandasでpd.concatした後、drop_duplicates()する事と同じ。

SELECT カラム名1
FROM テーブル名1
UNION
SELECT カラム名2
FROM テーブル名2; 

CROSS JOIN - 指定したカラム1とカラム2の全ての組み合わせを返す。pd.DataFrame.merge()でhow='outer'と指定する事と同じ。

SELECT テーブル1.カラム1, テーブル2.カラム2
FROM テーブル1
CROSS JOIN テーブル2; 


 とりあえず今回は以上です。もし何か間違いなどがありましたら遠慮なくご指摘ください。

この記事が気に入ったらサポートをしてみませんか?