WHERE句は、SELECT、UPDATE、DELETEなどの コマンドに指定します。コマンドで特定のレコードのみ処理したい場合に 、その特定する条件を指定します。
WHERE句を指定しない場合、テーブル内のすべてのレコードが処理され ます。
WHERE句は、ブール演算子で構成されます。ブール演算子は、真または偽 で評価する式です。複雑なWHERE句になると、ANDまたはOR により結合したブール演算式で構成されます。優先させたいブール式がある場合には、 括弧で囲んで優先順を制御します。
WHERE句は、演算式で比較することによって、フィールド値に基づいた レコードを限定することができます。以下に比較演算子を示します。
Table 13-1: WHERE句の比較演算子
演算子 | 概要 |
= | 一致 |
!= or <> or ~= | 不一致 |
! | 否定 |
> | より大きい |
>= | 以上 |
< | より小さい |
<= | 以下 |
IN | フィールド値の複数指定 |
RANGE ... | 値の上限値と下限値を指定 |
BETWEEN ... | RANGEと同一 |
LIKE | パターンマッチ(大文字、小文字の区別有り) |
MATCH | パターンマッチ(大文字、小文字の区別無し) |
SMATCH | パターンマッチ(大文字、小文字の区別有り) |
~は、!と同様に使用できます。
Syntax
WHERE | |b_expr |(b_expr) |b_expr OR b_expr |b_expr AND b_expr |NOT b_expr |
| | | | | |
説明
b_expr | ブール式です。詳細はブール式の評価を参照してください。 |
注意
|
|] condition | |
| | | |||||
|
| | |
expr 式。exprの定義は Expressionsを参照してください。
conditionは以下のいずれか1つです。
| | | | | | | |
|
| | | | | | | | |||||||||||||
| | | |
IN (expr {, expr}) IN subquery LIKE like_pattern [ESCAPE atom] |
| | | | |||||||||||||
| | | | |
|
| | | | | |||||||||||||
| | |
|
| | | | |||||||||||||
| | |
|
|
| | | ||||||||||||
| | |
|
|
| | |
subquery は以下に示す形式のクエリー言語コマンドです。
[ | |ANY |ALL |
|] (select_command) | |
like_pattern文字列を表します。 like_patternには、以下に示す特別な文字を組込むことが できます。
Table 13-2: LIKEパターンマッチング文字
文字 | 概要 |
_ (underline) | 指定位置には、任意の単一文字が許されます。 |
% | 指定位置には、任意の文字列が許されます。 |
atomは、(_)や(%)を単一のデータとして、Empressに解釈 させるために使用します。
subqueryのselect_commandは、1つ以上のフィールドに対する集計関数であり、唯一の項目を検索しなければなりません。 この時、GROUP BY句の指定、ヘッダーのPRINT句を使用することは できません。また必ず括弧で囲む必要があります。 サブクエリーについては、SQL:ユーザーズガイドを参照してください。
BETWEEN ANDは、RENGE TOと同様に使用できます。尚、値を指定 する場合には、必ず昇順で指定しなくてはなりません。 MATCHは、大文字、小文字の区別はしませんが、SMATCHは区別 します。MATCHの前に(!)を付加すると、マッチしない 全てのレコードが選択されます。LIKEもまた、大文字、小文字の区別をします。
expr = VALUE
このブール式は、真か偽、あるいはNULLのいずれかの結果を導きます。 式が何らかの原因で評価できなかった場合には、NULLとなります。
このように、ブール演算式は3種類の結果のうち、いずれか1つを導くので、複雑な ブール演算式を評価する上では、三値論理が必要となります。この論理から、 AND結合、OR結合したブール式の規則が決定されます。 以下に、そのテーブルを示します。
Table 13-3: AND結合
T | N | F | ||
T | T | N | F | |
N | N | N | F | |
F | F | F | F |
Table 13-4: OR結合
T | N | F | ||
T | T | T | T | |
N | T | N | N | |
F | T | N | F |
2つのブール演算式をAND結合した場合、ブール演算式全体が真になるには、 それぞれのブール演算式は、真でなくてはなりません。
2つのブール演算式をOR結合した場合、ブール演算式全体が真になるのは、 少なくとも、どちらか一方の演算式が真でなくてはなりません。
例えば、以下のような使い方をしたい場合、
... WHERE attr NOT = ANY SELECT ...
以下のように指定します。
... WHERE NOT (attr = ANY SELECT ...)
または、以下のように指定します。
... WHERE attr != ALL SELECT ...
パターンマッチでは、比較文字列に特殊文字を使用することが可能です。次に使用 できる特殊文字を示します。
文字 | 概要 |
? | 指定位置には、任意の単一文字が許可されます。 |
* | 指定位置には、任意の文字列が許可されます。 |
[...] | 指定位置には、指定文字セットのいずれかを許可します。 例、[abc]>/TT>はa、b、cが許可されます。 |
{...} | 指定位置には、0以上の文字列を許可します。 例、 {[a-z]}は、小文字に英字であれば全て許可します。 |
[.-.] | 指定位置には、指定範囲のいずれかの文字が許可されます。 例、[a-cf-i] は、a、b、c、f、h、iが許可されます。 |
[^...] | 指定位置には、指定文字セット以外のものを許可します。 例、 [^abc]は、a、b、c以外の文字を許可します。 |
...|... | "|"を境にして、どちらか一方の値で許可されます。 例、ab|cd は、abまたはcdが許可されます。 |
...&... | "&"を境にして、両方の値で許可されます。 例、[a-z]&[^x] は"x"以外の任意の文字に許可されます。 |
\ | "?"、"*"、"|"、"&"、"{"、"}"、"["、"]"、"\"などの特殊文字の前に、バックスラッシュを配置した場合、その文字は 特殊文字でなく、その文字自身として許可されます。 |
変数を拡張するために使用する文字の場合には、(MSQLVARCHARS変数で定義され、初期値はドル記号です)パターン マッチの用途はまったく無く、文字列におけるその変数拡張機能がそのまま維持されます。従って、この文字を文字列上、 またはパターン上の任意の位置に表現するには、2つのドル記号($$)を指定することにより、変数拡張機能を回避しなけれ ばなりません。
パターンマッチ例
例 | 概要 |
*ho* | このパターンを指定した場合、"ho"の前後に対応する文字の有無、および文字数には関係なく、 "ho"を構成している任意のフィールド値と照合することが可能です。例としてこのパターンは "ho"、"who"、"whom"、"Aho"、"hoho"、"Alphonse"などのフィールド値と一致します。 パターンの前の指定が、SMATCH(大文字、小文字を区別する)である場合には、英小文字の "ho"を使用したパターンが照合されます。パターンの前の指定が、MATCHである場合には、"ho"、 "HO"、"hO"、"Ho"というように、大文字、小文字の区別なしにパターンが照合されます。尚、MATCH、 SMATCHの前に"!"を指定した場合には、一致しないデータが検索されます。 |
12|13 | この場合、12または13とフィールド値が一致しなくてはなりません。 |
R*&*r | この場合、"Roger"などのRで始まり、rで終了する任意のフィールド値と一致しなくてなりません。 (R*rと指定することもできます。) |
*Jun*&*1990* | この場合、Junと1990を含んだフィールド値に限り一致します。例えば"12 June 1990"、"Jun. 12 1990"、 "1990 12 June"、"1990 June 12"、"on the 12th day of June in 1990"、その他いろいろな表記に 一致します。(従ってDATEデータタイプではなく、CHARデータタイプに自由に日付を入力する場合に 有効になります。) |
f?r | この場合、fで開始しrで終了する3文字からなる任意の文字列と一致します。例として"fur"、"for"、 "fir"、"far"などがあります。 |
f[uo]r | この場合、fで開始しrで終了する、中央の文字がuまたはoとなる3文字からなる文字列です。例として "fur"、"for"などです。 |
f[^i]r | もの場合、中央の文字がi以外の文字であれば、許可されます。例として、"fur"、"for"、"far"などです。 |
E_p | この場合、Eで始まり、pで終了する3文字からなる、全ての文字列と一致します。 |
例
SELECT * FROM personnel WHERE name = 'Jones';
以下を表示します。
number name phone credit_limit 3 Jones 667-2951 $500.00
SELECT * FROM personnel WHERE credit_limit >= 200.00;
以下を表示します。
number name phone credit_limit 10 Kilroy 426-9681 $500.00 5 Mosca 544-2243 $750.00 17 Wladislaw 723-6073 $200.00 3 Jones 667-2951 $500.00 8 Peterson 978-6060 $250.00
SELECT * FROM personnel WHERE name <> 'Kilroy' AND credit_limit = '$$500';
以下を表示します。
number name phone credit_limit 3 Jones 667-2951 $500.00
credit_limitの条件には、ドル記号を2つ指定していることに注意して ください。
SELECT * FROM loans WHERE date = '16 February 1990' OR name = 'Wladislaw';
以下を表示します。
name date amount Kilroy 16 February 1990 $250.00 Wladislaw 12 May 1990 $25.00 Wladislaw 27 February 1990 $55.00 Wladislaw 25 June 1990 $75.00
SELECT * FROM loans WHERE name = 'Jones' OR name = 'Kilroy' OR name = 'Mosca';
この方法とは別に、定数リストを使用して同一の処理を実行することができます。 以下のようなコマンドを実行します。
SELECT * FROM loans WHERE name IN ('Jones', 'Kilroy', 'Mosca');
これにより、複雑な構成で記述する必要がなくなります。
これと同様に、指定したもの以外の全てのレコードを選択することが可能です。 例えばloansテーブルの中から"Jones"、"Kilroy"、"Mosca"以外の全ての レコードを検索するには、次のように指定します。
SELECT * FROM loans WHERE name NOT IN ('Jones', 'Kilroy', 'Mosca');
以下のWHERE句は、phoneフィールドにデータが入力されて いないレコードを、すべて検索します。 キーワードNULLは、入力されていないデータを意味します。
SELECT FROM personnel WHERE phone = NULL;
以下のように出力します。
number name phone credit_limit
上記のように、phoneフィールドにはNULL値のレコードが検索 できないので、フィールド名だけが出力されます。 NULL値または、NULL値以外の値の検索には、 "="および"!="の代わりに、"is"および"is not" キーワードを使用することができます。
SELECT FROM personnel WHERE phone IS NULL;
SELECT FROM personnel WHERE phone IS NOT NULL;
上記は、phoneフィールドがNULLでないレコードを検索します。
以下のWHERE句は、nameフィールドが"Jones"で、 dateフィールドが"1 May 1990"より前のレコード、あるいは nameフィールドが"Wlasdislaw"で、dateフィールドが "30 April 1990"より後のレコードを検索します。 この場合、括弧を指定してグループ別に分類します。nameフィールドと dateフィールドが1つのグループとして条件を指定します。
ORは、括弧内の2つの条件を連結するために使用するので、 少なくともどちらか一方の条件が真でなくてはなりません。以下に示す例では、 それぞれの条件が同時に真になることはありません。
SELECT FROM loans WHERE (name = 'Jones' AND date < '1 May 1990') OR (name = 'Wladislaw' AND date > '30 April 1990');
以下を表示します。
name date amount Jones 7 February 1990 $33.95 Jones 3 April 1990 $25.00 Wladislaw 12 May 1990 $25.00 Wladislaw 25 June 1990 $75.00
括弧は、必要に応じて論理強調の目的で、WHERE句に指定することができ ます。
以下のWHERE句は、amountフィールドが credit_limitフィールドの半分を超えているレコードを検索する コマンドです。
SELECT name, date, amount FROM loans, personnel WHERE amount > 0.5 * credit_limit AND loans.name = personnel.name;
以下を表示します。
name date amount Jones 12 August 1990 $300.00 Scarlatti 9 September 1990 $150.00 Scarlatti 14 October 1990 $125.00
loansテーブルのnameフィールドに名前がある、 personnelテーブルのデータを表示します。
SELECT name, phone, credit_limit FROM personnel WHERE exists (SELECT name FROM loans WHERE loans.name = personnel.name);
以下を表示します。
name phone credit_limit Jones 667-2951 $500.00 Kilroy 426-9681 $500.00 Mosca 544-2243 $750.00 Peterson 978-6060 $250.00 Scarlatti 961-7363 $100.00 Wladislaw 723-6073 $200.00
以下のWHERE句は、loansテーブルの中から平均値未満の値を 持っているamountフィールドのレコードを検索します。そのためにクエリー をネストします。
SELECT FROM loans WHERE amount < (SELECT AVG amount FROM loans);
以下を表示します。
name date amount Jones 7 February 1990 $33.95 Wladislaw 27 February 1990 $55.00 Jones 3 April 1990 $25.00 Wladislaw 12 May 1990 $25.00 Peterson 6 June 1990 $50.00 Wladislaw 25 June 1990 $75.00
以下に示す例は、loansテーブルのamountフィールドの値が200 を超えている人の情報を、personnelテーブルから検索します。
SELECT name, credit_limit FROM personnel WHERE name= ANY (SELECT name FROM loans WHERE amount > 200);
name credit_limit Kilroy $500.00 Jones $500.00
以下のWHERE句は、"9"で始まるデータを持つphone フィールドの文字パターンレコードだけ検索します。 パターンマッチを利用した、検索条件の指定例を以下に示します。
SELECT * FROM personnel WHERE phone MATCH '9*';
以下を表示します。
number name phone credit_limit 8 Peterson 978-6060 $250.004 Scarlatti 961-7363 $100.00
以下のコマンドを指定しても、同一の処理結果となります。
SELECT * FROM personnel WHERE phone LIKE '9%';
以下のWHERE句は、任意の文字が先頭にあり(先頭になくても良い)、 その後1つのスペースが続き、"May"の後に、1つのスペースが続き、最後に任意の文字 がある(最後になくても良い)パターンと一致する、dateフィールド中の パターンレコードのみを検索します。この指定により、任意の年の5月に発生した loansテーブルのレコードを検索できます。
SELECT * FROM loans WHERE date MATCH '* May *';
以下を表示します。
name date amount Mosca 4 May 1990 $200.00 Wladislaw 12 May 1990 $25.00
dateフィールド中のデータで、唯一英文字であるのは、月の指定です。 Mayのエントリをすべて検出するための簡潔な指定方法は、以下の方法です。
SELECT * FROM loans WHERE date MATCH '*May*';
5月以外の月に発生した、レコードを検索するには、以下のコマンドを使用します。
SELECT * FROM loans WHERE date !MATCH '*May*';
または
SELECT * FROM loans WHERE date NOT LIKE '%May%';
以下を表示します。
name date amount Mosca 2 February 1990 $150.00 Jones 7 February 1990 $33.95 Kilroy 16 February 1990 $250.00 Wladislaw 27 February 1990 $55.00 Jones 3 April 1990 $25.00 Peterson 6 June 1990 $50.00 Wladislaw 25 June 1990 $75.00 Jones 12 August 1990 $300.00 Scarlatti 9 September 1990 $150.00 Scarlatti 14 October 1990 $125.00
SMATCHの効果については、auto partsテーブルからの検索に より、具体的に示すことができます。
SELECT supplier, phone, ATTR 'part name', price FROM 'auto parts' WHERE ATTR 'part name' SMATCH '*chrome*';
以下を表示します。
supplier phone part name price AAA Automotive 922-8624 Fender--chrome $67.95
ここでは、1レコードのみ表示しています。次のコマンドを使用した場合には、
SELECT supplier, phone, ATTR 'part name', price FROM 'auto parts' WHERE ATTR 'part name' MATCH '*chrome*';
以下の2レコードを表示します。
supplier phone part name price AAA Automotive 922-8624 Fender--chrome $67.95 Auto Wholesalers 922-6219 Chrome paint $1.99
尚、複合フィールド名で、演算式でないことを明示するために、フィールド名 part nameの前には、必ず"ATTR"キーワードを指定する必要があり ます。
値が与えられた範囲内に位置しているのを見つけるために、RANGE キーワードは、次のもののような 複雑なWHERE句に優先して使用します。
WHERE ATTRIBUTE first_constant AND ATTRIBUTE second_constant
RANGEの値を指定する際は、任意のレコードがその条件に合致するように、 必ず昇順に指定しなければなりません。降順にRANGEの値を指定しても、 エラーにはなりませんが、レコードは検索されません。 RANGE指定の、上限値および下限値は、省略時には範囲内に含まれます。 しかし、WHERE句の中でEXCLUSIVEを指定すれば、上限値および 下限値は、検索範囲から除外されます。
BETWEEN ... ANDは、RANGE ... TOの代わりに使用できます。
次の例は、loansテーブルのamountフィールドが、 100以上200以下のレコードを検索します。
SELECT name, date, amount FROM loans WHERE amount RANGE 100 to 200;
以下を表示します。
name date amount Mosca 2 February 1990 $150.00 Mosca 4 May 1990 $200.00 Scarlatti 9 September 1990 $150.00 Scarlatti 14 October 1990 $125.00
この結果に対して、以下のコマンドを実行した場合。
SELECT name, date, amount FROM loans WHERE amount RANGE 100 EXCLUSIVE TO 200 EXCLUSIVE;
以下を表示します。
name date amount Mosca 2 February 1990 $150.00 Scarlatti 9 September 1990 $150.00 Scarlatti 9 September 1990 $125.00
以下に示すWHERE句は、loansテーブルのamount フィールドの値が、200より大きく、300以下のレコードを検索します。
SELECT name, date, amount FROM loans WHERE amount RANGE 200 EXCLUSIVE TO 300;
以下を表示します。
name date amount Kilroy 16 February 1990 $250.00 Jones 12 August 1990 $300.00
値の範囲を指定するには、BETWEEN ... ANDを使用します。 BETWEEN ... ANDはRENGE ... TOの同義語として使用できます。 またBETWEEN ... ANDは、複雑なブール演算式を指定することもできますが、 その場合の評価の際には多くの時間を費やします。
SELECT * FROM table WHERE attr BETWEEN value AND value;
上記指定は、次の指定と同一です。
SELECT * FROM table WHERE attr RANGE value TO value;
よって、前に示したloansテーブルのamountフィールドのデータ が、100より大きく、200より小さいレコードの選択は、次のように指定することも可能 です。
SELECT name, date, amount FROM loans WHERE amount BETWEEN 100 EXCLUSIVE AND 200 EXCLUSIVE;
以下に示すような、同一の結果を表示します。
name date amount Mosca 2 February 1990 $150.00 Scarlatti 9 September 1990 $150.00 Scarlatti 9 September 1990 $125.00
尚、RENGE ... TOを指定した場合と同様に、任意のレコードがその条件に 合致するように、必ず昇順に値を指定しなければなりません。