MySQLにおけるデータ取得とフィルタリングの実践ガイド

関係データベースの構成要素とスキーマ設計

リレーショナルデータベースは、構造化された情報を格納・管理するために設計されています。主要な構成要素は以下の通りです。

  • テーブル (Table): データを格納する基本単位。データベース内で一意な名前を持つ必要があります。
  • カラム (Column): テーブル内の属性やフィールドを表します。
  • 行 (Row): 各レコードに対応するデータの集合です。
  • データ型 (Data Type): 各カラムに格納可能な値の種類を制限し、ストレージ最適化や正しいソート順序を保証します。
  • 主キー (Primary Key): 行を一意に識別するためのカラム(またはカラムの組み合わせ)。

主キーの制約と設計指針

主キーを定義する際には、以下の条件を厳密に遵守する必要があります。

  1. すべての行に値が存在するため、NULL は許可されません。
  2. テーブル内で値の重複は発生しません。

運用上の推奨事項として、主キーの値は設定後に更新しない、再利用しない、およびビジネスロジックの変更に伴う値(例:メールアドレスや電話番号)を使用しないことが挙げられます。

対話型シェルと基本取得コマンド

MySQLクライアントでの作業では、プロンプトmysql>に続けてコマンドを入力します。ステートメントはセミコロン(;)または\gで終了する必要があり、単にEnterキーを押すだけでは実行されません。ヘルプはhelpまたは\h、セッションの終了はquitまたは\exitで実行できます。

データベースの構造を確認するための主要なコマンドは以下の通りです。

-- データベース一覧の表示
SHOW DATABASES;

-- 現在のデータベースにあるテーブル一覧を取得
SHOW TABLES;

-- 特定テーブルの構造定義を確認(DESCRIBEと同義)
SHOW COLUMNS FROM product_catalog;

-- 作成時の完全なDDL文を出力
SHOW CREATE TABLE product_catalog;
SHOW CREATE DATABASE inventory_db;

-- サポートされているストレージエンジンの確認
SHOW ENGINES;

データ取得の基本構文では、特定カラムの指定や全カラムの取得(*)、重複排除、および出力件数の制限が可能です。

-- 特定カラムの抽出
SELECT item_code, product_name, price FROM product_catalog;

-- 重複値の除去(指定した全カラムの組み合わせで重複判定される)
SELECT DISTINCT category FROM product_catalog;

-- LIMITによる件数制限(0番目から5件取得)
SELECT item_code FROM product_catalog LIMIT 5;

-- LIMITの開始位置と件数を指定(2番目から5件)
SELECT item_code FROM product_catalog LIMIT 5 OFFSET 2;

-- データベース名とテーブル名を明示的に修飾
SELECT sku FROM inventory_db.product_catalog;

データの並び替えと条件フィルタリング

結果セットの順序を制御するにはORDER BY句を使用します。デフォルトは昇順(ASC)であり、降順にはDESCを指定します。日本語文字列のソート順序は照合順序(Collation)の設定に依存します。

SELECT item_code, price, stock_status 
FROM product_catalog 
ORDER BY price ASC, stock_status DESC;

行の抽出条件を定義するにはWHERE句を用います。比較演算子と組み合わせて条件式を構築します。

SELECT * FROM product_catalog 
WHERE price BETWEEN 1500 AND 8000 
ORDER BY price DESC;
演算子意味
=等しい
<> または !=等しくない
< / <=小さい / 以下
> / >=大きい / 以上
BETWEEN A AND B範囲内(A以上B以下)

BETWEENは数値および文字列の範囲指定に使用でき、境界値を含みます。また、欠損値の判定にはIS NULLを使用します。空文字列やゼロ値とは明確に区別されることに注意してください。

-- 文字列のマッチングはデフォルトで大文字小文字を区別しない
SELECT sku, product_name FROM product_catalog WHERE category = 'ELECTRONICS';

-- NULL値を持つレコードの抽出
SELECT sku, serial_number FROM product_catalog 
WHERE warranty_expires IS NULL 
LIMIT 5;

複合条件と集合演算子の優先順位

複数の条件を組み合わせる場合、ANDOR演算子を使用します。MySQLはANDを先に評価するため、意図しない結果を避けるために括弧による明示的なグループ化が必須です。

-- ANDのみ:両方の条件を満たす場合
SELECT sku, price FROM product_catalog 
WHERE stock_status = 'available' AND price >= 2000;

-- OR:いずれかの条件を満たす場合
SELECT sku, category FROM product_catalog 
WHERE category = 'BOOK' OR category = 'MAGAZINE';

括弧を使用しない場合と使用した場合で、評価順序が変化し、結果セットが大きく異なる点に留意してください。

-- 括弧なし(ANDが優先): status='discontinued'かつprice<500、またはcategory='SALE'
SELECT sku FROM product_catalog 
WHERE stock_status = 'discontinued' AND price < 500 OR category = 'SALE';

-- 括弧あり(明示的優先): (status='discontinued'またはprice<500) かつ category='SALE'
SELECT sku FROM product_catalog 
WHERE (stock_status = 'discontinued' OR price < 500) AND category = 'SALE';

複数の一致候補を指定する場合は、IN演算子を用いると記述が簡潔になり、実行計画が最適化されることが多いです。また、サブクエリをネストして動的な条件生成にも利用できます。

SELECT sku, product_name, price 
FROM product_catalog 
WHERE category IN ('AUDIO', 'VIDEO', 'CAMERA');

NOT演算子は条件を否定します。INBETWEENEXISTSなどの句と組み合わせ可能です。

SELECT sku, category FROM product_catalog 
WHERE category NOT IN ('BOOK', 'MAGAZINE');

パターン検索:LIKEと正規表現

曖昧な文字列検索にはLIKEREGEXPが使用されます。LIKEはカラム全体の値とマッチングを行うのに対し、REGEXPはカラム内の部分文字列に一致するパターンを検出します。

-- %:任意の文字(0文字以上)
-- _:任意の1文字
SELECT product_name FROM product_catalog 
WHERE product_name LIKE '%Adapter_' ;

正規表現検索では、REGEXPキーワードの後に標準的なパターン構文を記述します。MySQLのデフォルトでは大文字小文字を区別しませんが、BINARYを追加することで区別できます。

-- ORマッチング(|)
SELECT sku, serial_number FROM product_catalog 
WHERE serial_number REGEXP 'A|B|C';

-- 文字セット[]によるOR同等の表現
SELECT sku FROM product_catalog 
WHERE serial_number REGEXP 'SN[012]';
構文説明
[^abc]指定文字以外にマッチ
[a-z] または [0-9]範囲指定
*, +, ?0回以上, 1回以上, 0回または1回
{n}, {n,}, {n,m}正確n回, n回以上, n回からm回
[:digit:], [:alpha:], [:alnum:]文字クラス(数字, アルファベット, 英数字)

MySQL環境では、正規表現内の特殊文字やバックスラッシュ自体をエスケープするために、二重バックスラッシュ(\\)が必要です。

-- 数字が連続して出現するパターンの抽出
SELECT sku, price FROM product_catalog 
WHERE price REGEXP '^[[:digit:]]{4}$';

-- 単語境界とアンカーの活用
-- ^: 文字列の先頭, $: 末尾, [[:<:]]: 単語の開始, [[:>:]]: 単語の終了
SELECT product_name FROM product_catalog 
WHERE product_name REGEXP '^[[:alnum:]]{3}[[:digit:]]';

算出フィールドとエイリアスの定義

クエリ実行時に既存カラムを加工して新しい値を生成する際は、文字列関数や数値関数を使用します。複数の文字列を結合するにはCONCAT()関数が標準的です。他のDBMSでは||演算子が使われることもありますが、MySQLでは関数呼び出し形式が推奨されます。

-- 文字列結合
SELECT CONCAT(product_name, ' [', category, ']') AS display_info
FROM product_catalog
LIMIT 3;

結合前に不要な空白を除去するには、TRIM()(両端)、LTRIM()(左端)、RTRIM()(右端)を適用します。

SELECT CONCAT(TRIM(product_name), ': ', price) AS formatted_price
FROM product_catalog
ORDER BY price DESC;

生成された算出カラムや集計結果には、ASキーワードを使用して別名(エイリアス)を割り当てることができます。これにより、アプリケーション側でのデータ参照が容易になります。

SELECT 
  CONCAT(RTRIM(category), '_', sku) AS item_id,
  price * stock_count AS total_value
FROM product_catalog
WHERE stock_count > 0
ORDER BY total_value DESC;

タグ: mysql-sql-syntax data-filtering regular-expression-mysql query-optimization relational-database-basics

7月22日 17:50 投稿