SQL入門の導入スライド
SQL入門 - ファイルではなくデータベースを使う理由
保存するだけならファイルでもできる
在庫数をテキストファイルに書いておけば、たしかに保存はできます。それでも業務システムがデータベースを使うのは、保存できるかどうかとは別の理由があるからです。
1人で使っているうちは、この方法で何の問題も起きません。問題が出るのは2人目からです。
在庫数を書いたファイルを開くと、中身はこれだけです。
$ cat stock.txt
1001 / 3
SQL入門 - ファイルではなくデータベースを使う理由
2人が同時に直すとどうなるか
手順を最後まで送って、ファイルと DBMS の結果を見比べてください。
- 2人とも古い 100 を読んでから書くので、あとに書いたほうで上書きされる
- エラーは出ない。消えたことに誰も気づかないまま話が進む
- DBMS は読んだ行に鍵をかけて、片方を待たせることでこれを防ぐ
2 / 3
SQL入門 - ファイルではなくデータベースを使う理由
DBMS が肩代わりしていること
同時に触られたときの整理は、その一部にすぎません。自分で書くと大変なものを、DBMS があらかじめ引き受けてくれています。
この表の右側を扱う言葉が SQL です。次のレッスンから、その書き方に入ります。
| ファイルだと自分でやること | DBMS がやってくれること |
|---|---|
| 同時に書かれたときの順番付け | 行に鍵をかけて待たせる |
| 途中で落ちたときの巻き戻し | トランザクション |
| 変な値が入らないようにする | 型と制約 |
| 大量の行から目的の行を探す | インデックス |
| 誰がどこまで見てよいか | 権限 |
3 / 3
SQL入門 - なぜ表を分けて持つのか
1つの表に全部書いてみる
注文を記録する表に、ついでに顧客名とメールも書いておけば、その表を見るだけで済みます。実際に書いてみると、同じ人が2回目の注文をした時点で困りごとが出てきます。
同じメールが2行に書かれています。3回目、4回目と注文が増えたらどうなるかを、次の枚で見てください。
田中さんが 2 回注文すると、表はこうなります。
注文ID 顧客名 メール 金額
1001 田中 tanaka@x.com 2500
1003 田中 tanaka@x.com 13001 / 4
SQL入門 - なぜ表を分けて持つのか
1つの表に詰め込むと何が起きるか
トグルを入れて、同じメールが何か所に出るかを数えてください。
- 混ぜたままだと、メールを直すのに注文の行数だけ直すことになる
- 1行でも直し忘れると、同じ人なのに違うメールが記録として残る
- 分けておけば直す場所は1か所。注文の側には顧客IDだけが残る
2 / 4
考えてみよう外しても進めます
顧客の表と注文の表を分けたあと、注文の 顧客ID に customers に存在しない番号を書いたらどうなると思いますか。
選ぶと、この枚の中で答えと理由を確かめられます。
3 / 4
SQL入門 - なぜ表を分けて持つのか
分けた表をつなぐ2つの列
orders の 顧客ID を動かして、矢印が customers のどの行に着くかを見てください。
- 主キーは、その表の中で1行を一意に指す列。customers.顧客ID がそれ
- 外部キーは、別の表の主キーを指す列。orders.顧客ID がそれ
- 99 のように一致する主キーが無いと、矢印は宙に浮いたまま着地しない。この2つをたどって表をつなぎ直すのが、あとで出てくる JOIN
4 / 4
データベースの仕組み
データベースは、こういう表の形でデータを持っています。この表そのものをテーブルと呼び、縦の列をカラム、横の行をレコードと呼びます。
products
| 商品ID | 商品名 | 価格 |
|---|---|---|
| 10001 | 商品A | 2500 |
| 10002 | 商品B | 1000 |
| 10003 | 商品C | 1300 |
縦に見れば商品IDだけが並び、横に見れば商品1件ぶんがまとまっています。
データベースが持つ表は1枚だけではありません。顧客の表、注文の表と、用途ごとに何枚も抱えています。
1 / 5
SQL入門 - テーブル・行・列の基本
表のどこを何と呼ぶか
ボタンを押して、表のどこを指す言葉なのかを見てください。
- 縦の並びが列。商品ID なら商品ID だけ、価格なら価格だけが入る
- 横の並びが行。商品1件ぶんの情報がここにまとまっている
- この表そのものがテーブル。データベースは表を何枚も持っている
2 / 5
SQL入門 - テーブル・行・列の基本
同じものに呼び方が2つある
現場では日本語と英語が混ざって飛んできます。指しているものは同じなので、対応だけ先に押さえておくと、あとの話が全部読めるようになります。
SQL は結局、この表から行を選び、列を選ぶだけの言葉です。
| 現場で聞く言い方 | 同じものを指す言葉 |
|---|---|
| テーブル | 表 / relation |
| 列 | カラム / column / 項目 |
| 行 | レコード / row / 1件 |
| セル | 1行1列が交わったところの値 |
3 / 5
列には型が決まっている
表を作るときに、列ごとに「ここには何が入るか」を先に宣言します。決めておくと、価格の列に文字を入れようとした時点で DBMS が断ってくれます。
products表の名前name VARCHAR(50)列の名前と型products
| id | name | price |
|---|---|---|
| 10001 | 商品A | 2500 |
| 10002 | 商品B | 1000 |
| 10003 | 商品C | 1300 |
宣言した3つの列に沿って、行が積み上がっていきます。
囲った1行が1レコード。商品C という1件ぶんの情報が横一列に並んでいます。
4 / 5
考えてみよう外しても進めます
products の表から「価格が 2000 円以上の商品」を出したいとき、選んでいるのは行と列のどちらですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
SQL入門 - 主キーとNULL制約
PRIMARY KEY は2つを同時に守る
行を1本に決めるには、主キー列に NULL も同じ値も許せません。
id INT PRIMARY KEY は、id に NOT NULL と UNIQUE を同時に効かせます。
| 条件 | 主キー列での約束 |
|---|---|
| NOT NULL | すべての行に値が入る |
| UNIQUE | 全行を通じて値が重複しない |
| PRIMARY KEY | 2つを同時に満たし、行を一意に識別する |
1 / 4
変わる値を主キーにしない
メールアドレスのような業務上の値は、あとで変わることがあります。識別だけを担う id を主キーにすると、業務の変更から切り離せます。
自然キー(email など)
業務上の意味を持つ あとで変更されることがある 変更の影響が広がりやすい
サロゲートキー(id)
業務とは無関係な連番・UUID 識別専用として変更しない email の重複は UNIQUE で守る
users では id を PRIMARY KEY、email の重複は UNIQUE で別に守ります。
2 / 4
SQL入門 - 主キーとNULL制約
NULLを許す列、許さない列
NULL は 0 や空文字ではなく、「値が存在しない・不明・該当しない」を表す特別な状態です。
必須か、未登録・未確定の状態を持つかを、列ごとに決めます。
| users の列・値 | 設計上の扱い |
|---|---|
| id / name / email | 必須:NOT NULL |
| phone | 未登録がある:NULL を許す |
| 0 / 空文字 '' | 値そのもの:NULL ではない |
3 / 4
未登録ユーザーだけを取り出す
phone = NULL は TRUE ではなく UNKNOWN になり、WHERE には残りません。NULL を探すときは IS NULL を使います。
phone IS NULL未登録だけを残すORDER BY id ASCid の昇順実行結果
| id | name | phone | |
|---|---|---|---|
| 2 | 鈴木 | suzuki@example.com | NULL |
| 4 | 高橋 | takahashi@example.com | NULL |
2件:id=2、id=4。phone はどちらも NULL です。
ORDER BY id ASC まで書いて、期待される2行の順序を固定します。
4 / 4

SELECT と FROM を1組で書く
SELECT の後ろに返してほしい列を並べ、FROM の後ろに読み出すテーブルを書きます。
name, price返す列を左から順に書くproducts読み出すテーブル列名はカンマで区切り、セミコロンでSQL 1文の終わりを示します。
1 / 4
SQL入門 - SELECT文の基本構文
書いた列だけが結果に残る
「*」「name, price」「name」を切り替え、stock 列を足す前後で結果の幅を比べます。
- 指定を変えても3行は変わらず、結果の列数だけが変わる
- * は、その時点でテーブルにあるすべての列を返す
- stock を追加しても、明示した列の結果は変わらず、* の結果だけが1列広がる
2 / 4
SQL入門 - SELECT文の基本構文
出力列には名前と式も置ける
AS の右側は結果の見出しになり、計算式や固定値も出力列として並べられます。
これは追加チャレンジ用のプレビューです。通常の2列課題とは分けて試します。
| やりたいこと | SELECT に書く形 |
|---|---|
| 列に見出しを付ける | name AS 氏名 |
| 計算した値を1列にする | salary * 12 AS 年収 |
| 固定値を1列にする | '正社員' AS 雇用形態 |
3 / 4
4列から2列へ絞る
employees には5件の社員がいます。必要な列だけを指定すると、行は減らずに結果の幅だけが変わります。
期待する結果セット
| name | department |
|---|---|
| 田中 一郎 | 営業部 |
| 佐藤 花子 | 開発部 |
| 鈴木 次郎 | 人事部 |
| 高橋 三郎 | 開発部 |
| 伊藤 四郎 | 営業部 |
5行×2列。SELECT に書いた順で name、department が並びます。
4 / 4
WHERE は TRUE の行だけを残す
SQL は SELECT・FROM・WHERE の順で書きます。WHERE の条件が TRUE になった行だけが結果に残ります。
name, category結果に返す列products読み出すテーブルWHERE category = '文具'TRUE の行だけ残すこれは追加チャレンジ「文具だけを抽出」の非採点プレビューです。通常課題とは分けて試します。
1 / 2
SQL入門 - WHERE句で条件絞り込み
TRUE の行だけが残る
価格の下限を動かして、products の7行から残る行を確かめます。
- price >= 下限 が TRUE の行だけが結果に残る
- 1000円では id 1・5・6 の3行が残る
- 2600円では0行。空の結果も正しい結果
2 / 2
NULL は値が無いのではなく不明
NULL は空文字でも 0 でもありません。「分からない」という状態です。分からない値と何かを比べても、答えはやはり分かりません。
usersどの表からemail = NULLここが罠結果
| name | |
|---|---|
| 佐藤 | a@example.com |
| 鈴木 | NULL |
| 田中 | b@example.com |
| 加藤 | NULL |
1行も返りません。エラーも出ません。
= NULL は必ず 0 行になります。NULL の行すら返らないのが、いちばん引っかかる点です。
1 / 4
考えてみよう外しても進めます
WHERE email != 'a@example.com' は、この4行のうち何行を返すと思いますか。
選ぶと、この枚の中で答えと理由を確かめられます。
2 / 4
SQL入門 - NULL の扱い
真でも偽でもない
条件を切り替えて、返る行数がどう変わるか見てください。
- = NULL は 0 行。IS NULL なら 鈴木 と 加藤 の2行
- != でも NULL の行は返らない。「違う」も判定できない
- 真・偽のほかに「不明」がある、と考えると筋が通る
3 / 4
SQL入門 - NULL の扱い
NULL の扱い早見
比較演算子は NULL に効きません。NULL を相手にするときは、専用の書き方に切り替えます。
この4行なら COUNT(*) は 4、COUNT(email) は 2 になります。COUNT が2種類あるのではなく、集計関数が NULL を数えないからです。
| やりたいこと | 書き方 |
|---|---|
| NULL かどうか | IS NULL |
| NULL でないか | IS NOT NULL |
| NULL を別の値に | COALESCE(email, '未登録') |
| NULL を数えない | COUNT(email) |
| 全行を数える | COUNT(*) |
4 / 4
GROUP BY で行を束ねる
WHERE が行を捨てるのに対して、GROUP BY は行を束ねます。同じ値を持つ行がひとかたまりになり、そのかたまりごとに1行が出ます。
COUNT(*)束ねたあとの計算empどの表からGROUP BY dept束ねる列結果
| dept | COUNT(*) |
|---|---|
| 営業 | 2 |
| 開発 | 3 |
5行が2行になります。dept の値ごとに1行です。
行が捨てられたのではありません。営業の2行が1行に束ねられただけです。
1 / 4
考えてみよう外しても進めます
GROUP BY dept のあと、SELECT に name を足すとどうなると思いますか。
選ぶと、この枚の中で答えと理由を確かめられます。
2 / 4
SQL入門 - GROUP BY で束ねて数える
束ねると値が1つに決まる
集計を切り替えたあと、SELECT に name を足してみてください。
- 営業は 30 と 40 の2行が束ねられて1行になる
- AVG に変えると営業は 35。COUNT の 2 とは別の計算
- name を足すと、束ねた行に書ける値が無いのでエラーになる
3 / 4
SQL入門 - GROUP BY で束ねて数える
集計の早見
束ねたかたまりに対して何を計算するかを決めるのが集計関数です。よく使うものと、絞り込みの書き分けを先に押さえます。
WHERE は束ねる前、HAVING は束ねたあとに効きます。「平均が 40 以上の部署だけ」は WHERE では書けません。
| やりたいこと | 書き方 |
|---|---|
| 行数 | COUNT(*) |
| 合計 | SUM(salary) |
| 平均 | AVG(salary) |
| 最大 / 最小 | MAX(salary) / MIN(salary) |
| 束ねる前の絞り込み | WHERE |
| 束ねたあとの絞り込み | HAVING |
4 / 4
JOIN で2つの表を噛み合わせる
users には注文が入っておらず、orders には名前が入っていません。両方を1つの結果で見るために、どの行とどの行が同じものを指すのかを ON で書きます。
users u左の表orders o右の表u.id = o.user_id何をそろえるか結果
| name | item |
|---|---|
| 佐藤 | 本 |
| 佐藤 | ペン |
| 鈴木 | ノート |
| 鈴木 | 付箋 |
| 田中 | — |
田中 は注文が1件も無いので、結果から消えます。
消えた 田中 を残したいときに LEFT JOIN を使います。このあとの図解で切り替えます。
1 / 4
考えてみよう外しても進めます
users と orders をカンマで並べて FROM に書くと、3行と4行で何行になると思いますか。
選ぶと、この枚の中で答えと理由を確かめられます。
2 / 4
SQL入門 - INNER JOIN で表をつなぐ
つなぎ方で結果が変わる
つなぎ方を切り替えて、結果が何行になるか数えてください。
- INNER は相手のいない 田中 が消える
- LEFT は 田中 が残り、item に NULL が入る
- カンマでつなぐと 3 × 4 で 12 行。線が全部と全部に引かれる
3 / 4
SQL入門 - INNER JOIN で表をつなぐ
つなぎ方の早見
JOIN の種類は「相手がいない行をどうするか」の違いだけです。先に対応を覚えておくと、あとのレッスンで迷いません。
表をカンマで並べると CROSS JOIN と同じ結果になります。JOIN の ON を書き忘れた場合はエラーで止まりますが、カンマはエラーが出ないので、行数が急に増えたら真っ先に疑う場所です。
| やりたいこと | 書き方 |
|---|---|
| 両方にある行だけ | INNER JOIN |
| 左を全部残す | LEFT JOIN |
| 右を全部残す | RIGHT JOIN |
| そろえる条件 | ON a.x = b.y |
| 同じ列名でつなぐ | USING (id) |
| 総当たり | CROSS JOIN |
4 / 4
SQL入門 - WHERE句のサブクエリ
内側を先に解いて、その答えで絞る
手順を進めて、内側の戻り値が外側の比較相手になるところを見てください。
戻り値が複数なら = は使えません。内側が何行返すかで演算子が決まります。
1 / 1
SQL入門 - INSERT で行を追加する
列と値は前から順に対応する
3つの場合を切り替えて、どこで対応が崩れるか見てください。
- INSERT で書くのは、表の名前と、列の並びと、値の並びの3つ
- 列と値は前から順に1対1で結ばれる
- 数が合わない文は、実行される前に弾かれる
1 / 5
作成ボタンの先で動いているもの
画面から見ると「作成する」を押しただけですが、その裏では3つの場所を順番に通っています。SQL が出てくるのは3番目です。
フロントエンド
入力された値をサーバーへ送る
サーバーサイド
受け取った値で INSERT 文を組み立てる
データベース
表に行を1本増やす
フロントエンド
返ってきた一覧を描き直す
このレッスンで書くのは3行目です。画面もサーバーも、最後はこの1文にたどり着きます。
2 / 5
どの表のどの列に、何を入れるか
INSERT は3つの部品でできています。表の名前、値を入れる列の名前、そして入れる値です。
memosどの表に足すか(name)値を入れる列'とまと'入れる値memos
| id | name |
|---|---|
| 1 | じゃがいも |
| 2 | にんじん |
| 3 | たまねぎ |
| 4 | とまと |
囲った行が増えた1本です。id は自動で採番されるので、書いていません。
列の並びと値の並びは前から順に対応します。数が合わないとエラーになります。
3 / 5
ここでつまずく
INSERT は形が単純なぶん、間違いもいつも同じところに出ます。
列名をまるごと省く
全部の列に値を並べる約束になる
文字列を裸で書く
列の名前だと解釈されてエラー
値の数が列より多い
実行されずにエラー
id を自分で書く
自動採番とぶつかることがある
エラーで止まるのはむしろ助かる側です。黙って入ってしまう間違いのほうが、あとで探すのに苦労します。
4 / 5
考えてみよう外しても進めます
memos の表に3行入っている状態で、同じ INSERT 文を2回実行するとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
SQL入門 - UPDATE で行を書き換える
WHERE が決めるのは範囲
WHERE の行を外して、書き換わる行がどこまで広がるか見てください。
- UPDATE は、何に書き換えるかの SET と、どれを書き換えるかの WHERE でできている
- WHERE を省いた文はエラーにならない。表の全行が同じ値になって正常に終わる
- 書く前に同じ条件で SELECT を流し、返ってきた行数を見るのが現場の手順
1 / 5
作成との違いは、どの行かを送ること
編集画面で直して送ったあとに通る場所は、作成のときと同じ3つです。違うのは、送るものと、データベースでやることの2点だけです。
INSERT のとき
送るのは値だけです。表に行が1本増えて、対象はその新しい行になります。
UPDATE のとき
値と、どの行かを一緒に送ります。既にある行の値が書き換わり、対象は WHERE で選んだ行になります。
「どの行か」を送っている点が作成との差です。これが文の中では WHERE になります。
2 / 5
SET が新しい値、WHERE が対象の行
UPDATE は2つの役割に分かれています。何に書き換えるかが SET、どれを書き換えるかが WHERE です。
SET name = 'とまと'新しい値WHERE id = 3書き換える行memos
| id | name |
|---|---|
| 1 | じゃがいも |
| 2 | にんじん |
| 3 | とまと |
3行目だけが書き換わりました。他の行には触れていません。
SET は列ごとにカンマで並べられます。触れなかった列の値はそのまま残ります。
3 / 5
WHERE を書き忘れると全行が変わる
UPDATE の WHERE は省略できます。省略した文はエラーになりません。表の全行が同じ値に書き換わったうえで、正常終了します。
UPDATE memos対象は表そのものmemos
| id | name |
|---|---|
| 1 | とまと |
| 2 | とまと |
| 3 | とまと |
3行とも同じ値になりました。元の値はもう表のどこにも残っていません。
書く前に同じ条件で SELECT を流し、返ってきた行数を見てから UPDATE に直すのが、現場で使われている手順です。
4 / 5
考えてみよう外しても進めます
UPDATE memos SET name = 'とまと' WHERE id = 99; を、id が 99 の行が無い表に実行するとどうなりますか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5
SQL入門 - DELETE で行を消す
消える単位は文で変わる
3つの文を切り替えて、消える単位がどう変わるか見てください。
- DELETE が消すのは行。WHERE で選んだぶんだけ表から無くなる
- WHERE を省くと全行が消える。それでもエラーにはならない
- DROP TABLE が消すのは表そのもの。列の名前も一緒に消える
1 / 5
更新との違いは、戻せないこと
通る場所は作成や更新と同じです。違うのは、送るものが減ることと、やり直しが効かないことの2点です。
UPDATE のとき
新しい値を送ります。行は表に残るので、書き戻せば元に戻ります。
DELETE のとき
値は要らず、どの行かだけを送ります。行が表から取り除かれ、戻せるのはバックアップからだけです。
消えた行は SELECT で探しても出てきません。だから消す前に、本当に消すのかを決めておきます。
2 / 5
DELETE には SET が無い
消すのに新しい値は要らないので、DELETE にあるのは「どの表か」と「どの行か」の2つだけです。
memosどの表からWHERE id = 3消す行memos
| id | name |
|---|---|
| 1 | じゃがいも |
| 2 | にんじん |
3行目が表から消えました。id の 3 が空くだけで、下の行が繰り上がることはありません。
列を消すのは DELETE ではありません。あれは表の形を変える話なので ALTER TABLE の仕事です。
3 / 5
SQL入門 - DELETE で行を消す
消す前に決めておくこと
業務のデータは、消すと困るものが混ざっています。本当に取り除くのか、消えたことにするだけなのかを先に決めます。
削除フラグのやり方を論理削除と呼びます。表からは消えないので、以降の SELECT では毎回そのフラグで絞ることになります。
| やり方 | 向いている場面 |
|---|---|
| DELETE で本当に消す | 作業中の下書きなど、残す価値が無いもの |
| 削除フラグを立てる | 注文履歴など、あとから見返すもの |
| WHERE を省く | 無い。全行が消える |
| TRUNCATE を使う | 表を空にすると決めているとき |
4 / 5
考えてみよう外しても進めます
注文履歴の表から、退会した人の注文を DELETE で消しました。困るのはどれですか。
選ぶと、この枚の中で答えと理由を確かめられます。
5 / 5