「SQLって何?」
4月から新しいメンバーが入ってくるので、研修資料を準備しています。で、「SQLってそもそも何ですか?」という質問に対して、Excel前提で説明したらけっこうスムーズに伝わったので、そのときの説明をメモとして残しておきます。
プログラミング経験ゼロ、Excelは仕事で使ってる、くらいの人を想定しています。
SQLをひとことで言うと
ざっくり言うと「データベースに対して質問するための言語」です。
Excelだと、データを目で見て、フィルターかけて、関数で集計しますよね。SQLはそれを文章(命令文)で書いてやる感じです。マウスでポチポチやる代わりに、テキストで「こういうデータちょうだい」と頼む。
なんでわざわざそんなことをするかというと、Excelだと扱いきれない量のデータがあるからです。数万行くらいならExcelでもいけますが、数百万行、数千万行になるとExcelは固まります。SQLならそのくらいの量でも普通に動きます。
ExcelとSQLの対応表
ここが一番伝わりやすかったところです。Excelの操作とSQLの命令を並べてみます。
| Excelでやること | SQLで書くと |
|---|---|
| シートを開く | FROM テーブル名 |
| 列を選ぶ | SELECT 列名 |
| フィルターをかける | WHERE 条件 |
| 並び替え | ORDER BY 列名 |
| 重複を除く | SELECT DISTINCT |
| COUNTIF / SUMIF | GROUP BY + COUNT() / SUM() |
| VLOOKUP | JOIN |
| シートのコピー&加工 | CREATE TABLE / INSERT |
これを見せたら「あ、Excelでやってることを文字で書くだけなんですね」って言ってもらえました。まさにそうです。
具体的にどう書くか
社員名簿みたいなテーブルがあるとします。
-- employees テーブル
| id | name | department | salary |
|----|--------|------------|--------|
| 1 | 田中 | 営業 | 300000 |
| 2 | 鈴木 | 開発 | 350000 |
| 3 | 佐藤 | 営業 | 280000 |
| 4 | 山田 | 開発 | 400000 |
| 5 | 高橋 | 総務 | 320000 |
Excelで言うとシートに入っている表です。SQLではこれをテーブルと呼びます。
全部見る(シートを開く)
SELECT * FROM employees;
* は「全部の列」という意味です。Excelでシートを開いて全体を眺めるのと同じ。
特定の列だけ見る
SELECT name, department FROM employees;
結果:
| name | department |
|------|------------|
| 田中 | 営業 |
| 鈴木 | 開発 |
| 佐藤 | 営業 |
| 山田 | 開発 |
| 高橋 | 総務 |
Excelで言うと、不要な列を非表示にする感じです。
フィルターをかける(WHERE)
SELECT * FROM employees WHERE department = '営業';
結果:
| id | name | department | salary |
|----|------|------------|--------|
| 1 | 田中 | 営業 | 300000 |
| 3 | 佐藤 | 営業 | 280000 |
Excelのフィルターで「営業」だけ選ぶのと同じです。
条件は組み合わせられます。
-- 営業部で、給与が29万以上
SELECT * FROM employees
WHERE department = '営業' AND salary >= 290000;
これはExcelだとフィルターを2つかけるか、複合条件でフィルターする操作ですね。
並び替え(ORDER BY)
SELECT * FROM employees ORDER BY salary DESC;
DESC は降順(大きい順)。ASC が昇順(小さい順)で、省略すると ASC になります。Excelの「大きい順に並べ替え」と同じです。
集計する(GROUP BY)
ここからちょっとExcelとの対応が変わってきます。
SELECT department, COUNT(*) AS 人数, AVG(salary) AS 平均給与
FROM employees
GROUP BY department;
結果:
| department | 人数 | 平均給与 |
|------------|------|----------|
| 営業 | 2 | 290000 |
| 開発 | 2 | 375000 |
| 総務 | 1 | 320000 |
Excelだとピボットテーブルでやる操作です。部署ごとに人数と平均給与を出しています。
COUNT(*) が COUNTIF に、AVG() が AVERAGEIF に対応する感じ。他にも SUM()、MAX()、MIN() があります。名前のまんまなので覚えやすいです。
「ピボットテーブルを文字で書いてる感じ」と言ったら、みんな納得してくれました。たぶんこの例えが一番しっくりくると思います。
VLOOKUPの代わり(JOIN)
もう1つテーブルがあるとします。
-- departments テーブル
| name | floor |
|--------|-------|
| 営業 | 3F |
| 開発 | 5F |
| 総務 | 2F |
社員の名前と、所属部署のフロアを一緒に出したい。Excelなら VLOOKUP で別シートから引っ張ってきますよね。
SELECT employees.name, employees.department, departments.floor
FROM employees
JOIN departments ON employees.department = departments.name;
結果:
| name | department | floor |
|------|------------|-------|
| 田中 | 営業 | 3F |
| 鈴木 | 開発 | 5F |
| 佐藤 | 営業 | 3F |
| 山田 | 開発 | 5F |
| 高橋 | 総務 | 2F |
ON のあとに書いてあるのが「どの列を手がかりにくっつけるか」です。VLOOKUPの検索値と同じ役割ですね。
VLOOKUPは列の位置を番号で指定するので、列が増えるとズレたりしてイライラしますよね。SQLの JOIN は列名で指定するので、そういう事故が起きにくいです。ここは地味にうれしいポイント。
SQLが使えるとうれしいこと
研修で「なんでExcelじゃダメなんですか?」って聞かれたので、こう答えました。
- データ量の壁がない。 Excelは数万行を超えると重くなるし、100万行でシートの上限に達します。SQLは数億行でも動きます。業務データって想像以上に多いので、この差はわりとすぐ実感すると思います。
- 再現性がある。 Excelだと「フィルターかけて、この列でソートして、ピボットテーブル作って…」という手順を毎回マウスでやりますよね。SQLは命令文をコピペすればいつでも同じ結果が出ます。先月と同じ集計を今月もやりたい、みたいなときに楽です。
- ミスに気づきやすい。 Excelで複雑な関数を組むと、どこかのセルが壊れていても気づきにくい。SQLは書いた命令がそのまま処理の記録になるので、レビューしやすいです。
逆に、ちょっとした計算や簡単なグラフを作るなら、Excelのほうが早いです。SQLは万能ではないので、使い分けの感覚は仕事しながら掴んでいけばいいと思います。
SQLを触ってみるには
実際に手を動かしたいなら、ブラウザで動くSQL練習サイトがあります。環境構築なしで試せるのでおすすめです。
自分が研修で使ったのは、DB Fiddle というサイトです。ブラウザ上でテーブルを作ってSQLを実行できます。「まずはこの記事のSQLをコピペして動かしてみて」と伝えたら、30分くらいで SELECT と WHERE は書けるようになっていました。
ローカルで動かしたい場合は SQLite が手軽です。インストールも軽いし、ファイル1つでデータベースが作れます。ただ、最初はブラウザのほうがハードルが低いと思います。
所感
SQLの研修、最初は公式ドキュメント的な説明をしていたんですが、反応がいまいちで。「Excelで言うと何?」に置き換えた途端にみんなの目が変わりました。
考えてみたら、SELECT とか WHERE とか言われても、まだ頭の中に対応するイメージがないんですよね。Excelの操作という「すでに知っていること」に紐づけてあげると、理解のスピードが全然違いました。
この記事では SELECT、WHERE、ORDER BY、GROUP BY、JOIN しか触れていませんが、実務で使うSQLの8割くらいはこれで書けます。残りは必要になったときに調べれば十分です。最初から全部覚えようとすると心が折れるので、まずはこの5つだけ。
ここまで読んでいただき、ありがとうございます。もしこの記事の技術や考え方に少しでも興味を持っていただけたら、ネクストのエンジニアと気軽に話してみませんか。
- 選考ではありません
- 履歴書不要
- 技術の話が中心
- 所要時間30分程度
- オンラインOK