MySQL 入門

MySQL WHERE 句

デフォルトの状態では、SELECT ステートメントはテーブル内のすべての行を取得します。しかし、実際のアプリケーションにおいて、テーブルの全レコードを必要とすることは極めて稀です。WHERE 句は「ゲートキーパー(門番)」のような役割を果たし、行が結果セット(Result Set)に返される前に、特定の条件に基づいてフィルタリングを行います。通常、WHERE 句は FROM 句の後、かつソート(ORDER BY)や制限(LIMIT)ロジックの前に記述されます。

1. フィルタリングクエリの構造

WHERE 句を追加すると、データベースはターゲットテーブル内の各行に対してその条件を評価します。条件の評価結果が TRUE(真)であれば、その行は出力に含まれます。FALSE(偽)または UNKNOWN(不明。主に NULL 値の場合)であれば、その行は破棄されます。

-- 人口が100万人を超える都市の名前と人口を取得する
SELECT name, population FROM city WHERE population > 1000000;

このクエリは、MySQLに対して city(都市)テーブルを参照し、各行の population(人口)カラムをチェックして、人口が厳密に100万人より大きい行だけを返すように指示しています。

2. 比較演算子

MySQLは、フィルタリング条件を定義するための標準的な演算子を提供しています。これらを効果的に使用できるかどうかは、演算子とカラムのデータ型が一致しているかどうかにかかっています。

演算子意味使用例
=等しいWHERE countrycode = 'USA'
<> または !=等しくないWHERE language != 'English'
<より小さいWHERE gnp < 5000
<=以下WHERE surfacearea <= 1000
>より大きいWHERE population > 5000000
>=以上WHERE year >= 2000

3. 文字列と日付の処理

数値の比較とは異なり、クエリで文字列を扱う場合は必ずシングルクォーテーション(' ')で囲む必要があります。デフォルトの標準的なキャラクタセットの照合順序(Collation)では、MySQLは通常大文字と小文字を区別しません。そのため、'USA''usa' は通常同じ結果を生成します。

-- district(行政区)が 'California'(カリフォルニア)の行を照会
SELECT * FROM city WHERE district = 'California';

-- 特定のフラグでレコードを照会(例:公式フラグが 'T' のもの)
SELECT * FROM countrylanguage WHERE isofficial = 'T';

4. データベースによるフィルタリング処理の流れ

データベースエンジン内部での操作の順序を可視化することは非常に重要です。WHERE 句は、クエリのライフサイクルの中でも非常に早い段階で処理されます。

  1. FROM テーブル: まず、データのソース(情報源)を特定します。
  2. WHERE フィルタリングの適用: 各行に対して条件判断を行います。
    • 条件を満たす(TRUE) → カラムを選択(SELECT) → 最終的な結果セットに追加
    • 条件を満たさない(FALSE/UNKNOWN) → 行を破棄
  3. SELECT: 最終的に残った行から、要求されたカラムのみを抽出します。

5. エッジケースとデータ型の取り扱い

初心者が陥りやすい罠は、すべてのデータ型が数値と同じように振る舞うと仮定してしまうことです。

  • 精度 (Precision): WHERE 句で浮動小数点数(Float/Double)を扱う場合、= 演算子の使用には注意が必要です。コンピュータの低層での浮動小数点演算の保存方式により、値が厳密に 10 ではなく 10.000000001 となっている可能性があるからです。クエリの安定性を高めるには、範囲指定(例:>= 10 AND <= 10.00001)を使用するのが賢明です。
  • 日付フォーマット (Date Formats): MySQLが期待するデフォルトの日付フォーマットは YYYY-MM-DD(年-月-日)です。もし文字列が MM-DD-YYYY の形式であれば、MySQLはそれを有効な日付オブジェクトとして正しく変換できず、クエリ結果が返されないか、エラーが発生します。
  • 暗黙の型変換 (Implicit Conversion): 文字列型のカラムを数値と比較した場合(例:WHERE name = 123)、MySQLは文字列を数値に変換しようと試みます。これは非常に危険であり、重大なパフォーマンス問題を引き起こす可能性があります。なぜなら、データベースエンジンはこの「全行に対する型変換」を行うために、インデックス(Index)の使用を放棄せざるを得なくなるからです。比較する値は、常にカラムのデータ型と一致させるようにしてください。