WHERE句を使ってレコードを検索する場合,AND,OR,INなどを利用すれば複雑な条件の検索が可能です。ただし,テーブルの結合時にテーブル名付きの列名にしなかったり,インデックスを利用できないようなSQLの書き方だと,SQLの検索パフォーマンスが低下する場合があります。このほかトランザクション処理を実装することで,SQLの一連の更新処理を「なかったこと」にすることもできます。

 SELECT文でレコードを引き出すと,同じデータがいくつも入っていることがあります。例えば,Part1で作成したt_hanbaiテーブルから,納品日(ndate)のデータを引き出すと,7月12日というデータが二つ見つかります(図1)。

図1●MySQLを使ってt_hanbaiテーブルからndataのデータを取り出した。7月12日のレコードが2件ある
図1●MySQLを使ってt_hanbaiテーブルからndataのデータを取り出した。7月12日のレコードが2件ある

 レコード数が少ないうちはあまり問題になりませんが,レコードが増えてくると,重複するデータは一つにまとめて表示したいという場合も出てきます。例えば,「xxさんに納品したのはいつだったかな」といった場合です。

 このようなときに役立つのが「DISTINCT」句です。t_hanbaiテーブルから納品日を調べるときにDISTINCT句を使って「SELECT DISTINCT ndate FROM t_hanbai;」として実行してみてください。重複していた「2005-07-12」というレコードが1件だけになっています(図2)。

図2●DISTINCT句を使うと,二つあった7月12日のレコードが一つにまとまる
図2●DISTINCT句を使うと,二つあった7月12日のレコードが一つにまとまる

 これがDISTINCT句の効果です。ある商品が売れたのは何日と何日かを知りたいときなどにも役立ちますね。ちなみに図1で実行した

SELECT ndate FROM t_hanbai;

というSQL文は,全レコードを表示するという意味の「ALL」句を省略したものです。

SELECT ALL ndate FROM t_hanbai;

として実行しても同じ結果が得られます。

複雑な条件を設定して合致するレコードだけを取り出す

 SELECT文にWHERE句を組み合わせると,特定の条件に合ったレコードだけを取り出せることはPart1で説明しました。また,指定した範囲内にあるレコードを選択する「WHERE BETWEEN」も紹介しました。複数の条件を「AND」や「OR」でつなげられることも少しだけ説明しました。ここでは,ANDやORの使い方をもう少し詳しく見ていきましょう。

 ANDで二つの条件をつなげると,二つの条件の両方を満たすレコードを引き出せます。言い方を変えると,二つの条件の論理積を求めることになります(図3(a))。

図3●AND(論理積)とOR(論理和)の使い分け。ANDは二つのグループの重なる部分を指し,ORは二つのグループの全体を指す
図3●AND(論理積)とOR(論理和)の使い分け。ANDは二つのグループの重なる部分を指し,ORは二つのグループの全体を指す

 SQL文の実例を見てみましょう。

SELECT shcd,shname,tanka FROM t_syohin WHERE kigou='SDMC' AND tanka < 5000;

を実行してください。t_syohinテーブルから,分類記号(kigou)がSDMCで,かつ単価(tanka)が5000円未満の商品のレコードを表示するはずです。t_syohinテーブルには10個のレコードが入っていますが,このSQL文を実行してみると,商品コード(shcd)が100101と100102のレコードだけが出てきます。

 一方,ORで条件をつなげると,二つの条件のどちらかを満たしているレコードを取り出します。論理和を求めるということですね(図3(b))。

 先ほどと同様,t_syohinテーブルを使ってORの機能を確認してみましょう。

SELECT shcd,shname,tanka FROM t_syohin WHERE kigou='SDMC' OR tanka < 5000;

を実行してください。今度は,分類記号がSDMC,または単価が5000円未満のどちらかの条件を満たすレコード(7件)を表示します。

 条件を範囲で指定するだけでなく,具体的な値で指定することもできます。これには「IN」を使います。構文は以下の通りです。

WHERE 列名 IN (候補値1,候補値2,候補値3,…)

 INの後に並べた候補値のどれかと合致するレコードを引き出します。例えば

SELECT shcd,shname,kigou,tanka FROM t_syohin WHERE kigou IN('SDMC','SM');

を実行してみましょう。t_syohinテーブルから分類記号が「SDMC」と「SM」のレコードをそれぞれ引き出します(図4)。

図4●INを使うと,具体的な候補値を挙げて検索できる。この例では,kigouがSDMCとSMのレコードを検索している
図4●INを使うと,具体的な候補値を挙げて検索できる。この例では,kigouがSDMCとSMのレコードを検索している

 INの進んだ使い方として,NOTと一緒に使う方法も覚えましょう。INの前にNOTを入れて

WHERE 列名 NOT IN (候補値1,候補値2,候補値3,…)

と記述して実行すると,候補値を含まないレコードを選択できます。同様に,WHERE BETWEENも「WHERE 列名 NOT BETWEEN A AND B」とすると範囲外のレコードを選択できます。

この先は会員の登録が必要です。今なら有料会員(月額プラン)が12月末まで無料!

日経 xTECHには有料記事(有料会員向けまたは定期購読者向け)、無料記事(登録会員向け)、フリー記事(誰でも閲覧可能)があります。有料記事でも、登録会員向け配信期間は登録会員への登録が必要な場合があります。有料会員と登録会員に関するFAQはこちら