STAGE 03 — 3-2 / 絞り込みと並べ替え

AND・OR・NOTで条件を組み合わせる

考えてみよう

「火星出身」で、なおかつ「年齢が30以上」の乗員を探したいとき、WHERE句を1つ書くだけで足りるでしょうか?

前回はWHERE句に「1つの条件」を書きました。では「2つ以上の条件を同時に満たす行」を探したいときは、どう書けばいいでしょう。少し考えてから読み進めてください。

複数条件を組み合わせるAND・OR・NOT

複数の条件を1つのWHERE句にまとめるには、ANDORNOTという3つの論理演算子を使います。

crewテーブルで確認しましょう。

crew テーブル:

idnameroleagehomesalary
1ユミエンジニア24地球320000
2ケンジパイロット35火星400000
3サクラ医師41地球520000
4ハルト医師33450000
5レイ研究員29火星380000
6ミドリパイロット27地球360000
7ソラエンジニア45470000
8トウマ研究員24NULL270000
9アカリエンジニア31火星350000
10リョウパイロット38NULL440000

「火星出身」かつ「年齢30以上」を探すならANDです。

SELECT name, home, age
FROM crew
WHERE home = '火星' AND age >= 30;

結果:

namehomeage
ケンジ火星35
アカリ火星31

「医師」または「研究員」を探すならORです。

SELECT name, role
FROM crew
WHERE role = '医師' OR role = '研究員';

結果:

namerole
サクラ医師
ハルト医師
レイ研究員
トウマ研究員

「地球出身ではない」をNOTで書くと、こうなります。

SELECT name, home
FROM crew
WHERE NOT home = '地球';

結果:

namehome
ケンジ火星
ハルト
レイ火星
ソラ
アカリ火星

地球出身以外の5名が返ってきました。これはWHERE home != '地球'と書いたときとまったく同じ結果になります。

ここで気をつけたいのが、配属先(home)が未定でNULLになっているトウマとリョウです。この2人はどちらの書き方でも結果に含まれません。なぜなら、NULLとの比較(home = '地球')は「真」でも「偽」でもなく「不明(わからない)」という特別な状態になり、NOTで反転させても「不明」は「不明」のままだからです。「わからない」の反対もやっぱり「わからない」、という感覚です。トウマとリョウのようにNULLの行まで拾いたいときは、home IS NULLを使います(IS NULLの使い方は次回くわしく学びます)。

優先順位とカッコ

AND・ORを一緒に使うときは、優先順位に注意が必要です。SQLではANDORより先に評価されます。

たとえば「地球出身または火星出身の、エンジニア」を探したいとして、次のように書いてしまうとどうなるでしょうか。

SELECT name, home, role
FROM crew
WHERE home = '地球' OR home = '火星' AND role = 'エンジニア';

一見良さそうですが、ANDが先に評価されるため、実際には「home = '地球'またはhome = '火星' かつ role = 'エンジニア'」という意味になってしまいます。これでは地球出身の全員(ユミ・サクラ・ミドリ)が、役割に関係なく含まれてしまい、意図とズレます。

意図どおりに書くには、カッコ()でまとめます。

SELECT name, home, role
FROM crew
WHERE (home = '地球' OR home = '火星') AND role = 'エンジニア';

結果:

namehomerole
ユミ地球エンジニア
アカリ火星エンジニア

カッコで囲んだ部分が先に計算されるので、「地球か火星の出身者」という条件をひとまとめにしてから、「エンジニアである」という条件をANDでかけ合わせられます。複数条件を組み合わせるときは、AND/ORが混ざったら迷わずカッコをつける——これを習慣にしておくと、意図しない結果を防げます。

確認問題

「役割がパイロットで、かつ年齢が35以上、または医師である」乗員を探したいとき、正しいWHERE句はどちらでしょう? WHERE role = 'パイロット' AND age >= 35 OR role = '医師'WHERE (role = 'パイロット' AND age >= 35) OR role = '医師'

答えを見る

どちらも実は同じ結果になります。SQLではANDORより先に評価されるため、カッコがなくてもrole = 'パイロット' AND age >= 35が先にまとまり、その結果にOR role = '医師'が続きます。ただし、読む人に意図を明確に伝えるためにも、カッコを書く習慣をつけておくのがおすすめです。

条件を自在に組み合わせられるようになると、データベースへの質問はぐっと表現力を増します。次回は「あいまいな条件」や「範囲」「リスト」での絞り込みを学びます。

/sql/game/ の SQL DIVER で、AND・OR・カッコの感覚を指先に覚えさせておきましょう。

ゆみちゃん
ゆみ

ANDとORが混ざったら、とにかくカッコ! これさえ守れば、意図しない結果に振り回されることはないよ。