Day6 後半
条件を「組み合わせて」「あいまいに」検索する感覚を固める
前半で、AND / OR と LIKE の基本的な意味はつかめました。
後半では、それらを組み合わせて使うことで、実際のサービスに近い検索をイメージできるところまで持っていきます。
「日本語の条件」→「SQLの条件」に変換する練習だと思って読んでください。
AND / OR と LIKE を組み合わせるイメージ
「年齢で絞ってから、名前であいまい検索する」
まず、前半で使った users テーブルをもう一度前提にします。
id | name | age | email
---+------------+-----+----------------------
1 | 山田太郎 | 25 | taro@example.com
2 | 佐藤花子 | 19 | hanako@example.com
3 | 鈴木一郎 | 30 | ichiro@example.com
4 | 高橋健 | 22 | ken@example.com
5 | 田中花子 | 28 | hanako.t@example.com
ここから、次のような日本語の条件を考えます。
「20歳以上 かつ 名前に『田』が含まれるユーザー」
これは、
年齢の条件:age >= 20
名前の条件:name LIKE '%田%'
を、AND でつなげばよい、ということになります。
SQL にするとこうです。
SELECT * FROM users
WHERE age >= 20
AND name LIKE '%田%';
SQL結果は、
山田太郎(25, 「田」を含む) → 該当
田中花子(28, 「田」を含む) → 該当
となります。
id | name | age | email
---+------------+-----+----------------------
1 | 山田太郎 | 25 | taro@example.com
5 | 田中花子 | 28 | hanako.t@example.com
ここで大事なのは、
「数値条件(age >= 20)と文字列条件(name LIKE '%田%')を、同じ WHERE の中で自然に混ぜている」
という感覚です。
OR と LIKE を組み合わせる
「名前に『田』が含まれるか、メールに ‘hanako’ が含まれる人」
次は、少し広い条件を考えます。
「名前に『田』が含まれる または メールアドレスに ‘hanako’ が含まれるユーザー」
日本語で分解すると、
名前条件:name LIKE '%田%'
メール条件:email LIKE '%hanako%'
これを OR でつなぎます。
SELECT * FROM users
WHERE name LIKE '%田%'
OR email LIKE '%hanako%';
SQLテーブルを見ながら判定してみます。
山田太郎
名前に「田」あり → 該当
佐藤花子
名前に「田」はないが、メールに hanako を含む → 該当
鈴木一郎
どちらも該当しない → 不該当
高橋健
どちらも該当しない → 不該当
田中花子
名前に「田」あり、メールにも hanako を含む → 該当
結果はこうなります。
id | name | age | email
---+------------+-----+----------------------
1 | 山田太郎 | 25 | taro@example.com
2 | 佐藤花子 | 19 | hanako@example.com
5 | 田中花子 | 28 | hanako.t@example.com
OR を使うと、「どちらか一方でも条件を満たせばOK」なので、結果が広がることを体感しておいてください。
AND と OR を混ぜるときの落とし穴
「どこまでがセットなのか」を意識する(かっこで守る)
少しだけレベルを上げて、こんな条件を考えます。
「20歳以上 かつ(名前に『田』が含まれる または メールに ‘hanako’ が含まれる)」
日本語で見ると、
年齢条件:age >= 20
名前 or メール条件:name LIKE '%田%' OR email LIKE '%hanako%'
という構造になっています。
SQL にするときは、「どこまでが OR のセットなのか」をはっきりさせるために、かっこ () を使います。
SELECT * FROM users
WHERE age >= 20
AND (
name LIKE '%田%'
OR email LIKE '%hanako%'
);
SQLこのように書くと、
まず () の中で「名前に田が含まれる or メールに hanako が含まれる」を判定し、
そのうえで「かつ 20歳以上」という条件をかける、という順番になります。
かっこを付けずにこう書いてしまうと、
WHERE age >= 20
AND name LIKE '%田%'
OR email LIKE '%hanako%';
SQL「AND が OR より先に評価される」というルールのせいで、意図と違う結果になることがあります。
Day6 の段階では、「AND と OR を混ぜるときは、かっこでグループをはっきりさせる」と覚えておけば十分です。
LIKE のパターンをもう少しだけ増やす
「前方一致」「後方一致」「部分一致」を言葉で区別する
LIKE と % の組み合わせには、よく使うパターンが3つあります。
前方一致:'田%' → 「田で始まる」
後方一致:'%田' → 「田で終わる」
部分一致:'%田%' → 「どこかに田を含む」
たとえば、「メールアドレスが ‘example.com’ ドメインのユーザーだけ欲しい」ときは、後方一致を使います。
SELECT * FROM users
WHERE email LIKE '%@example.com';
SQL'%@example.com' は、「前に何文字あってもよいが、最後は @example.com で終わる」という意味です。
逆に、「社内メール(先頭が ‘internal_’ で始まるアドレス)だけ欲しい」といった場合は、前方一致を使います。
SELECT * FROM users
WHERE email LIKE 'internal_%';
SQL'internal_%' は、「internal_ で始まり、その後に何文字か続く」という意味です。
結果が「多すぎる」「少なすぎる」ときの考え方
条件・演算子・ワイルドカードのどこがズレているかを疑う
あいまい検索や複雑な条件を使い始めると、次のようなことが起きやすくなります。
思ったより行数が多い。
思ったより行数が少ない(あるいは0件)。
このときに見直すべきポイントは、だいたい次の三つです。
比較演算子が合っているか(> と < を逆にしていないか)。AND と OR を取り違えていないか。LIKE のパターン(% の位置)が意図どおりか。
たとえば、「名前に『田』が含まれる人」を取りたいのに、うっかりこう書いてしまうと、
WHERE name LIKE '田%';
SQL「田で始まる人」しか取れません。'%田%' に直すと、「どこかに田を含む人」になります。
この「結果を見て違和感を覚えたら、条件のどこがズレているかを疑う」という姿勢は、バグ防止だけでなく、セキュリティ上も重要です。
意図しない広すぎる検索は、そのまま情報漏洩のきっかけになり得るからです。
セキュリティの視点から見る LIKE とあいまい検索
「取りすぎない」「ログに残しすぎない」という意識
LIKE '%...%' は、とても強力な検索です。
しかし、そのぶん「想定より多くのデータを取ってしまう」リスクもあります。
管理画面などで、
「とりあえず LIKE '%xxx%' で検索しておこう」
と乱用すると、本来見せる必要のないデータまで一気に取得してしまうことがあります。
また、検索結果がログに残る場合、
「広すぎる条件で検索 → ログに大量の個人情報が残る」
という事故パターンもあります。
だからこそ、
本当に部分一致が必要か?
前方一致や後方一致で十分ではないか?
そもそも、もっと絞った条件にできないか?
といった視点を、エンジニアとして常に持っておくことが大切です。
小さな練習で締める
日本語 → SQL に変換する癖をつける
頭の中で、次の日本語を SQL にしてみてください。
「20歳以上 かつ 名前に『田』を含むユーザー」
「名前に『花』を含む または メールに ‘hanako’ を含むユーザー」
「メールアドレスが ‘@example.com’ で終わるユーザー」
全部、WHERE に AND / OR / LIKE と % を組み合わせるだけで書けます。
スラスラ出てこなければ、Day6 前半・後半の例を見ながら、何度か手で書いてみてください。
Day6 後半のまとめ
AND / OR と LIKE を組み合わせることで、「現実の検索」に近い条件が書ける。() を使って、「どこまでが OR のセットか」をはっきりさせると、意図しない結果を防げる。LIKE の前方一致・後方一致・部分一致を言葉で区別して使い分ける。
結果が多すぎる・少なすぎるときは、演算子・AND/OR・% の位置を疑う。
あいまい検索は便利だが、「取りすぎない」「ログに残しすぎない」というセキュリティ意識もセットで持つ。
