Q1SELECT * FROM staff WHERE salary BETWEEN 5000000 AND 6000000;の説明として正しいものはどれですか。
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 で書けるようになります。
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 5000000 AND 6000000は5,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 が含まれてしまうので注意してください。
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 と`=`で大小区別ルールが違う
本講座のコンソール(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 文字を選べます。実務で_や%を含むコード列を検索するときに使う書き方です。
WHERE と ORDER BY と LIMIT を組み合わせる
実務のクエリは、絞り込み(WHERE)→ 並び替え(ORDER BY)→ 件数制限(LIMIT)を組み合わせて書くのが基本パターンです。句の書く順序は固定で、順序を入れ替えると構文エラーになります。
DB が実行する順序はおおむね FROM → WHERE → SELECT → ORDER BY → LIMIT で、まず行を絞り込み、必要な列を選び、並び替えてから件数を切り出す、という流れです。
理解度チェック
まずは1問ずつ答えてみましょう。
Q2name LIKE '%Tanaka'のパターンに一致する名前はどれですか。
Q3次のクエリで「順序が正しい」ものはどれですか。