diff --git a/src/pages/sql/010-foundation.mdx b/src/pages/sql/010-foundation.mdx index 113839a..b50ecb1 100644 --- a/src/pages/sql/010-foundation.mdx +++ b/src/pages/sql/010-foundation.mdx @@ -66,6 +66,8 @@ [引用 - 同姓同名のペアができる確率をExcelで計算したら予想よりも高かった件。](https://note.com/yudo_tanaka/n/ndddef4b15d95) これが多いか少ないかはさておき、名前で人を特定することが難しい場合があることがわかります。 +複数の箇所で名前が登録されているとき、それが同一人物なのか別人なのかを判断することができません。 + これを回避して確実に1人を特定するために、`ID`を割り当てているのです。 なお、SQLの世界では、`ID`は主に **主キー (Primary Key)** として使われます。 diff --git a/src/pages/sql/040-join.mdx b/src/pages/sql/040-join.mdx index 873266f..2795d49 100644 --- a/src/pages/sql/040-join.mdx +++ b/src/pages/sql/040-join.mdx @@ -2,9 +2,97 @@ layout: "@/layouts/MarkdownLayout.astro" --- -export const title = "テーブルをまとめて扱う:JOIN"; +export const title = "テーブルを分ける、繋げる"; import DockerLink from "@/components/DockerLink.astro"; import OuterLink from "@/components/OuterLink.astro"; # {title} + +## テーブルを分ける + +例えば、なにか観た映画の率直な感想をデータベースで管理したいとします。 + +テーブル名: **movies** + +| 作品名 | ラベル | +| :----- | :---- | +| インセプション | おもしろい、感動的 | +| マトリックス | おもしろい、難しい | +| 君の名は。 | 感動的、絵がきれい | +| 天空の城ラピュタ | 感動的、面白い | + +このテーブルには、いくつかの問題点があります。 +1つずつ見ていきましょう。 + +さてこの中で、面白いと評価された映画を抽出したいとします。 + +```sql +SELECT * FROM movies WHERE label LIKE '%面白い%'; +``` + +
+結果 + +| 作品名 | ラベル | +| :----- | :---- | +| 天空の城ラピュタ | 感動的、面白い | + +`インセプション`と`マトリックス`が抽出されません。それもそのはず、`おもしろい`と`面白い`は別の文字列だからです。 + +では、SQLの条件に`OR`で繋げればいいのでしょうか? + +```sql +SELECT * FROM movies WHERE label LIKE '%おもしろい%' OR label LIKE '%面白い%'; +``` + +
+ +| 作品名 | ラベル | +| :----- | :---- | +| インセプション | おもしろい、感動的 | +| マトリックス | おもしろい、難しい | +| 天空の城ラピュタ | 感動的、面白い | + +確かに見た目上は、すべて抽出できました。 +しかし、この面白いという評価は、他にも`おもろい`など、様々な表現があるかもしれません。 + +いま登場した`おもしろい`、`面白い`、`おもろい`などのように、同じ意味を持つが異なる表現を**同義語**と呼びます。 +これをすべてSQLの条件に`OR`で繋げていくのは、あまりにも非効率です。 + +このような問題を解決するために、テーブルを分けて管理する方法があります。 +以下のようなテーブルを用意してみました。 + +テーブル名: **movie_labels** + +| ID | ラベル | +| --: | :---- | +| 1 | おもしろい | +| 2 | 感動的 | +| 3 | 難しい | +| 4 | 絵がきれい | +| ~ | \~中略\~ | +| 10 | 自分の好み | + +`movies`テーブルのラベル列を、この`movie_labels`テーブルのIDを使うようにしてみます。 + +| 作品名 | ラベルID | +| :----- | :---- | +| インセプション | 1,2 | +| マトリックス | 1,3 | +| 君の名は。 | 2,4 | +| 天空の城ラピュタ | 2,1 | + +これで、おもしろいと評価する映画を抽出するSQLは、以下のようになります。 + +```sql +SELECT * FROM movies WHERE label_id LIKE '%1%'; +``` + +
+ +| 作品名 | ラベルID | +| :----- | :---- | +| インセプション | 1,2 | +| マトリックス | 1,3 | +| 天空の城ラピュタ | 2,1 |