頻馬主義

競馬のデータをいろいろ見ていきます

【馬王Z SQL講座】 3つ以上の条件での抽出

1つの条件での抽出に関する記事はこちら

mare-ism.hatenablog.com

2つの条件での抽出に関する記事はこちら

mare-ism.hatenablog.com

3つ以上の条件

3つ以上の条件(条件A~条件Z)を使った基本的な構文は下記の通りです。

SELECT
    [カラム名]
FROM
    [テーブル名]
WHERE
    [条件式A] [論理演算子]
    [条件式B] [論理演算子]
    ...
    [条件式Z]
;

3つ以上の条件があったとしても、それぞれの条件式の間に論理演算子を記述していくことになります。

論理演算子の種類が混在している場合

ここでは論理演算子を AND と OR だけに限定して話を進めていきます。

WHERE句に書かれた複数の論理演算子が AND のみ、もしくは OR のみの場合は特に問題はないのですが、両方が混在している場合には注意が必要です。

今回はレースT テーブルから「条件A : 一着馬名がマツリダブロッコ」もしくは「条件B : 二着馬名がチュードサンデー」で「条件C : 競走名がエクセレント競走」のデータを抽出するケースを考えてみましょう。

これらの条件をWHERE句に書いて、次のようなクエリを作りました。

SELECT
    月日,
    競走名,
    一着馬名,
    二着馬名
FROM
    レースT
WHERE
    一着馬名 = "マツリダブロッコ" OR
    二着馬名 = "チュードサンデー" AND
    競走名 = "エクセレント競走"
;

このクエリを実行すると下図の結果が得られます。

f:id:mare_ism:20210420161508p:plain

競走名がエクセレント競走以外のデータも含まれています。どうしてでしょうか?

論理演算子の評価の順番

SQLではANDとORを混在して記述した場合はANDの方が先に評価されます。

なので、上に書いたクエリではまず「条件B : 二着馬名がチュードサンデー」かつ「条件C : 競走名がエクセレント競走」の部分が評価され(下図の水色部分)、

f:id:mare_ism:20210420162416j:plain

次に「条件A : 一着馬名がマツリダブロッコ」(下図のピンク色の部分)

f:id:mare_ism:20210420162506j:plain

との和集合(下図の濃い青色部分)

f:id:mare_ism:20210420162712j:plain

が抽出対象となります。

先に評価して欲しい条件は括弧でくくる

今回抽出したいデータは、「条件A : 一着馬名がマツリダブロッコ」もしくは「条件B : 二着馬名がチュードサンデー」(下図の水色部分)と

f:id:mare_ism:20210420163040j:plain

「条件C : 競走名がエクセレント競走」(下図のピンク色の部分)

f:id:mare_ism:20210420163349j:plain

との共通部分(下図の濃い青色部分)

f:id:mare_ism:20210420163502j:plain

なので、クエリは下記のようになります。

SELECT
    月日,
    競走名,
    一着馬名,
    二着馬名
FROM
    レースT
WHERE
    (一着馬名 = "マツリダブロッコ" OR 二着馬名 = "チュードサンデー") AND
    競走名 = "エクセレント競走"
;

このクエリを実行すると下図の結果が得られます。

f:id:mare_ism:20210420164038p:plain

このように、括弧の有無で実行結果が変わってきます。

ANDを先に評価して欲しい場合でも明示的に括弧を付けておいた方が抽出ミスを防げると思います。