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

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

WHERE 詳細の 2 本目です。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 の範囲(両端を含む)
BETWEEN の範囲(両端を含む)salary3,800,0004,500,000(両端)5,500,0006,000,000(両端)BETWEEN4500000〜6000000FALSETRUE(両端を含む)TRUETRUE(両端を含む)NOT BETWEEN4500000〜6000000TRUEFALSEFALSEFALSE
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次のクエリで「順序が正しい」ものはどれですか。