SQL BETWEEN: 数値と日付の包含範囲
SQL BETWEEN は、列の値が指定した範囲に入る行を両端を含めて絞り込みます。>= と <= の比較を 1 つの述語に置き換えられるため、包含範囲を扱う WHERE 句を短く保てます。BETWEEN は数値、日付、テキストで使えますが、日付範囲では時刻成分の扱いに注意が必要です。
範囲絞り込みのための SQL BETWEEN の例
出力:
ここに出力が表示されます...
出力:
+----------+-------+------------+
| customer | total | placed |
+----------+-------+------------+
| Ben | 120.5 | 2026-02-15 |
| Cara | 89.99 | 2026-02-20 |
+----------+-------+------------+
2 row(s)
この例の仕組み
CREATE TABLEとINSERTで、合計金額と日付が異なる 4 行のordersテーブルを用意します。WHERE total BETWEEN 50 AND 150はtotal >= 50 AND total <= 150の行だけを残します。境界値は両方含まれるため、ちょうど 50 や 150 の行も一致します。- 合計が 45.00 と 200.00 の行は範囲外なので除外されます。
x BETWEEN y AND z は x >= y AND x <= z と同じです。どちらかの境界が NULL の場合、この述語は UNKNOWN と評価され、その行は除外されます。
SQL BETWEEN とは?
SQL BETWEEN は、値が包含範囲に入っているかを判定します: column >= low AND column <= high。数値範囲では読みやすく、挙動も予測しやすい構文です。データベースによっては BETWEEN SYMMETRIC もサポートされ、境界が逆順でも自動で入れ替えて評価します。
SQL BETWEEN でよくある間違い
間違い: timestamp の範囲に BETWEEN を使う。
悪い例:
WHERE placed BETWEEN '2026-02-01' AND '2026-02-28'
正しい例:
WHERE placed >= '2026-02-01' AND placed < '2026-03-01'
理由: 列に時刻が含まれる場合、終了日 '2026-02-28' は通常その日の開始時刻にしか一致しません。1 日全体を含めるには半開区間を使います。
間違い: 境界を逆にして結果が出ると期待する。
悪い例:
WHERE total BETWEEN 150 AND 50
正しい例:
WHERE total BETWEEN 50 AND 150
理由: 通常の BETWEEN では最初の境界が下限である必要があります。境界を逆にすると条件は真になりません。
BETWEEN と IN と比較演算子の使い分け
| アプローチ | 使う場面 |
|---|---|
BETWEEN low AND high | 範囲が連続していて、両端を含めたい |
>= low AND < high | 上限を排他的にしたい(timestamp、ページネーション) |
IN (a, b, c) | 値が連続範囲ではなく離散的 |
> low AND < high | 両端を排他的にしたい |
原則: 数値の包含範囲には BETWEEN を優先します。片側を排他的にしたい場合は、特に日付では明示的な比較に切り替えます。値が固定集合なら IN を使います。BETWEEN だと、間の意図しない値まで一致してしまいます。
パフォーマンスに関する注意点
BETWEEN は sargable です。クエリプランナは >= AND <= と同様に扱い、絞り込み列の B-tree インデックスを利用できます。列を関数で包む (DATE(col), LOWER(col)) とインデックスが使えないため、代わりに境界値を正規化します。範囲が広いとインデックスがあっても読む行数は多くなるため、演算子の違いより選択性の方が重要です。
FAQ
SQL BETWEEN は包含ですか、それとも排他ですか?
BETWEEN は両端を含みます。WHERE x BETWEEN 5 AND 10 は x が 5、6、7、8、9、10 の行を返します。排他的な組み込み構文はないため、排他境界には > と < を使います。
BETWEEN はテキスト値にも使えますか?
はい。WHERE name BETWEEN 'A' AND 'M' は、現在の照合順序でその範囲に並ぶ名前を返します。結果はデータベースの照合順序ルールや大文字小文字の扱いに依存するため、本番で文字列範囲に依存する前に環境で確認してください。
BETWEEN が終了日当日のレコードを取りこぼすのはなぜですか?
列が datetime(日付 + 時刻)を保持している場合、'2026-02-28' のような上限はその日の開始時刻として解釈されることが多いからです。2 月 28 日の後半にある行は範囲外になります。1 日全体を含めるには半開区間(>= start AND < next_day)を使います。