順番に読み進めながら学べます

WHERE 詳細 ② — BETWEEN と LIKE で範囲・パターン絞り込み

この記事は、基礎から複雑なSQL,SQLチューニングまでSQLの実践的なスキルを1からマスターする「SQL入門講座の一部」です。
BETWEENによる範囲指定、NOT BETWEEN、LIKEの前方・後方・中間一致まで、CSVの社員データでORDER BY/LIMITと組み合わせて実行しながら学べます。

本記事で使うデータ — staff テーブル

WHERE 詳細の 2 本目は範囲指定(BETWEEN)パターンマッチ(LIKE)を扱います。前回のAND / OR / NOTで組み立てた複合条件と、本記事のBETWEEN / LIKEを組み合わせると、実務でよくある「範囲内のうち特定のパターン」「パターンに合致する複数候補」のような複雑な条件を 1 つの WHERE で書けるようになります。

演習に入る前に、staffテーブルの列定義データのサンプルを確認しておきます。

PRAGMA table_info(staff);で列名・型・主キーを確認してください。

SELECT * FROM staff LIMIT 5;で先頭 5 行のデータをプレビューしてください。

SQL エディタ

クエリを実行してください

BETWEEN — 値の範囲で絞り込む

「給料が 500 万円〜 600 万円」「生年月日が 2020 年 4 月〜 2025 年 3 月」のように、ある値が範囲に収まっているかを判定したいときに使うのがBETWEENです。

列 BETWEEN 値1 AND 値2と書くと、列の値が値1 以上 値2 以下の行を取り出します。両端を含む点に注意してください。列 >= 値1 AND 列 <= 値2と書くのと同じ意味で、可読性のために BETWEEN を選ぶ場面が多いです。

NOT BETWEENを付ければ、範囲の外に当たる行(値1 未満 または 値2 より大きい)を取り出せます。

-- 給料が 500 万円以上 600 万円以下の社員(両端を含む)
SELECT name, salary FROM staff
WHERE salary BETWEEN 5000000 AND 6000000;

-- 上の式と同じ意味(>= と <= の AND での書き換え)
SELECT name, salary FROM staff
WHERE salary >= 5000000 AND salary <= 6000000;

-- 範囲の外(500 万未満 または 600 万より大きい)
SELECT name, salary FROM staff
WHERE salary NOT BETWEEN 5000000 AND 6000000;
BETWEEN の範囲(両端を含む)
salary3,800,0004,500,000(両端)5,500,0006,000,000(両端)BETWEEN4500000〜6000000FALSETRUE(両端を含む)TRUETRUE(両端を含む)NOT BETWEEN4500000〜6000000TRUEFALSEFALSEFALSEBETWEEN の範囲(両端を含む)
BETWEEN 4500000 AND 6000000 は 4500000 と 6000000 を含む両端閉区間。NOT BETWEEN は逆に範囲の外側を取り出します。両端の値どうしをつなぐ点線が範囲の幅を表します。

BETWEEN は両端を含む

BETWEEN 5000000 AND 60000005,000,000 ちょうど6,000,000 ちょうど含みます。両端を含めたくない場合は> 5000000 AND < 6000000のように書きます。

日付に対して使う場合はBETWEEN '2020-04-01' AND '2025-03-31'のように書け、文字列リテラルとしてそのまま比較されます。「2025 年 3 月いっぱい」を含めたい場合は両端の日付指定で範囲を作るのが安全で、BETWEEN '2020-04-01' AND '2025-04-01'と書くと2025-04-01 が含まれてしまうので注意してください。

経営会議で「中堅層(給料 500 万円〜 600 万円)の人数を確認したい」という要件を想定します。(正しく実行できれば解説が表示されます)

staffテーブルからnamesalaryの 2 列を取り出してください。

salaryが 5,000,000 以上 6,000,000 以下の行に絞り込んでください(両端を含みます)。

③ 結果が 3 行(Bob 5,200,000 / Grace 5,500,000 / Jack 5,900,000)になることを確認してください。

SQL エディタ

クエリを実行してください

「中堅層(450 万 〜 600 万)から外れた社員一覧を給料の高い順で見たい」という要件を想定します。

staffテーブルからnamesalaryの 2 列を取り出してください。

salaryが 4,500,000 以上 6,000,000 以下の範囲外(つまり 4,500,000 未満 または 6,000,000 より大きい)に絞り込んでください。

③ 結果をsalaryの降順で並べてください。

④ 結果が 6 行になり、先頭が Frank 7,200,000、最後が Emi 3,800,000 になることを確認してください。

SQL エディタ

クエリを実行してください

LIKE — パターンマッチで絞り込む

「名前がTanakaで終わる人」「メールアドレスに@example.comを含む人」のように、文字列のパターンで絞り込みたいときに使うのがLIKEです。列 LIKE 'パターン'と書き、パターンの中で次の 2 つのワイルドカードが使えます。

ワイルドカード意味
%任意の0 文字以上の文字列に一致(任意の長さの「何でも」)
_任意の1 文字に一致(位置を固定した「何か 1 文字」)

'A%'A で始まる文字列、'%a'a で終わる文字列、'%a%'a を含む文字列、'A___%'A で始まり残りが 3 文字以上の文字列、というふうに組み合わせて使います。NOT LIKEを付ければパターンに一致しない行を取り出せます。

-- 1) 前方一致: 名前が A で始まる
SELECT name FROM staff WHERE name LIKE 'A%';

-- 2) 後方一致: 苗字が Tanaka
SELECT name FROM staff WHERE name LIKE '%Tanaka';

-- 3) 中間一致: 名前のどこかに 'a' を含む
SELECT name FROM staff WHERE name LIKE '%a%';

-- 4) 任意の 1 文字: 2 文字目が 'a' で残りは何でも
SELECT name FROM staff WHERE name LIKE '_a%';

-- 5) 否定: Tanaka で終わらない
SELECT name FROM staff WHERE name NOT LIKE '%Tanaka';
LIKE のワイルドカード(% と _)
パターン一致する例名前'A%'前方一致Alice / Adam /AppleA で始まる'%Tanaka'後方一致Alice Tanaka /Frank TanakaTanaka で終わる'%a%'中間一致Alice / David /Frank / Carola を含む'_a%'_ + %Carol / Dave /Jack2 文字目が a
% は「任意の長さの何でも」、_ は「ちょうど 1 文字」の意味。組み合わせ位置で前方一致 / 後方一致 / 中間一致の 3 パターンを表現できます。点線は「パターン → 一致する例 → 言葉での意味」の対応を示しています。

LIKE と`=`で大小区別ルールが違う

本講座のコンソール(SQLite)では、ASCII の範囲ではLIKE は大文字小文字を区別しませんname LIKE '%a%'name LIKE '%A%'は同じ結果を返します。区別したいときはPRAGMA case_sensitive_like = 1;を打つか、両辺をLOWER(...)で正規化します。

一方、SELECT 記事で扱った=での文字列比較は大小を区別します — =LIKEで挙動が違う点に注意してください。

`%`や`_`を文字どおりに検索したいとき — `ESCAPE`句

もし検索したい文字列に%_本物の文字として含まれていた場合(たとえば商品コード'A_001'を検索)、そのままだと_がワイルドカードとして解釈されてしまいます。ESCAPE句を使ってエスケープ文字を指定すると、その直後の% / _を文字として扱えます。

例: WHERE code LIKE 'A\_001' ESCAPE '\';\をエスケープ文字に指定し、\_を「文字としての _」として扱う)。エスケープ文字は\でなくてもよく、ESCAPE '#'#を、ESCAPE '!'!を、というふうに任意の 1 文字を選べます。実務で_%を含むコード列を検索するときに使う書き方です。

前方一致 / 後方一致 / 中間一致 の 3 パターンを 1 つのコンソールに並べて、結果の違いを確認します。

staffテーブルからnamecitysalaryの 3 列を取り出します。

nameがAで始まる(前方一致'A%')行を取り出してください。

③ 続けて、nameがTanakaで終わる(後方一致'%Tanaka')行を取り出してください。

④ さらに、nameの 2 文字目がa'_a%'_は任意の 1 文字)の行を取り出してください。

⑤ それぞれ 1 行 / 4 行 / 3 行になることを確認してください。

SQL エディタ

クエリを実行してください

WHERE と ORDER BY と LIMIT を組み合わせる

実務のクエリは、絞り込み(WHERE)→ 並び替え(ORDER BY)→ 件数制限(LIMIT)を組み合わせて書くのが基本パターンです。句の書く順序は固定で、順序を入れ替えると構文エラーになります。

句の書き順(左から右に並べる)
SELECTFROMWHERE条件ORDER BYLIMITNOFFSETM
SELECT 列 → FROM 表 → WHERE 条件 → ORDER BY 列 → LIMIT N OFFSET M の順で書きます。

DB が実行する順序はおおむね FROM → WHERE → SELECT → ORDER BY → LIMIT で、まず行を絞り込み、必要な列を選び、並び替えてから件数を切り出す、という流れです。

WHERE → ORDER BY → LIMIT の実行イメージ
1) WHEREname LIKE '%a%'→ 該当行に絞る (9 行)2) ORDER BYsalary DESC→ 給料の高い順に並び替え3) LIMITLIMIT 3→ 先頭 3 行を取り出す結果Frank 7,200,000David 6,800,000Henry 6,100,000
WHERE で行を絞り、ORDER BY で並び替え、LIMIT で先頭 N 件を切り出します。書く順序も実行される順序も、この並びで覚えれば迷いません。

ダッシュボードに「名前にaを含む社員」の給料ランキングを表示する、という要件を想定します。

staffテーブルからnamesalaryの 2 列を取り出してください。

name列にaを含む(中間一致)行に絞り込んでください。

salaryの降順で並べ、先頭 3 行に絞ってください。

④ 結果が 3 行(Frank Tanaka 7,200,000 / David Sato 6,800,000 / Henry Sato 6,100,000)になることを確認してください。

SQL エディタ

クエリを実行してください
QUIZ

理解度チェック

まずは1問ずつ答えてみましょう。

Q1SELECT * FROM staff WHERE salary BETWEEN 5000000 AND 6000000;の説明として正しいものはどれですか。

Q2name LIKE '%Tanaka'のパターンに一致する名前はどれですか。

Q3次のクエリで「順序が正しい」ものはどれですか。