こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

WHERE句でOR ANDを使うと抽出が変

SQLのwhere句について教えてください。Table_AとTable_Bはjoinされています。
下記の条件で、値を抽出したいです。型はintです。

Field1は必ずNULL
Field2は値が1~14のどれか。それ以外にはマッチしない
Field3は0か3のどちらかにマッチ。
Field4は2,3,4,8に以外にマッチ。
Field5は0,6のどちらかいにマッチ。
Field6はNULLを抽出
Field7はNULLを抽出

よって、下記のSQLを書きました。しかしながら、Field1~Field3まで抽出を
かけた時に、1万件だったのが、Field1~Field5までを含めると、1万2000件に
なってしまいます。なぜだかわかりません。何が間違っているかお教え
頂けないでしょうか?また正しいwhere句以下の条件はどのように正しく書けばいいのでしょうか?

WHERE
`TABLE_A`.`Field1` IS NULL AND
`TABLE_B`.`Field2` = 1 or
`TABLE_B`.`Field2` = 2 or
`TABLE_B`.`Field2` = 3 or
`TABLE_B`.`Field2` = 4 or
`TABLE_B`.`Field2` = 5 or
`TABLE_B`.`Field2` = 6 or
`TABLE_B`.`Field2` = 7 or
`TABLE_B`.`Field2` = 8 or
`TABLE_B`.`Field2` = 9 or
`TABLE_B`.`Field2` = 10 or
`TABLE_B`.`Field2` = 11 or
`TABLE_B`.`Field2` = 12 or
`TABLE_B`.`Field2` = 13 or
`TABLE_B`.`Field2` = 14 or
`TABLE_B`.`Field3` = 0 or
`TABLE_B`.`Field3` = 3 or
`TABLE_B`.`Field4` <> 2 or
`TABLE_B`.`Field4` <> 3 or
`TABLE_B`.`Field4` <> 4 or
`TABLE_B`.`Field4` <> 8 or
`TABLE_B`.`Field5` = 0 or
`TABLE_B`.`Field5` = 6 or
`TABLE_B`.`Field6` is NULL or
`TABLE_B`.`Field7` is NULL

投稿日時 - 2011-07-14 11:19:12

QNo.6874999

困ってます

質問者が選んだベストアンサー

条件が
Field1は必ずNULL
かつ
Field2は値が1~14のどれか。それ以外にはマッチしない
かつ
Field3は0か3のどちらかにマッチ。
かつ
Field4は2,3,4,8に以外にマッチ。
かつ
Field5は0,6のどちらかいにマッチ。
かつ
Field6はNULLを抽出
かつ
Field7はNULLを抽出
であれば

WHERE
(`TABLE_A`.`Field1` IS NULL) AND
(`TABLE_B`.`Field2` >= 1 AND
`TABLE_B`.`Field2` <= 14) AND
(`TABLE_B`.`Field3` = 0 or
`TABLE_B`.`Field3` = 3) AND
(`TABLE_B`.`Field4` <> 2 AND
`TABLE_B`.`Field4` <> 3 AND
`TABLE_B`.`Field4` <> 4 AND
`TABLE_B`.`Field4` <> 8) AND
(`TABLE_B`.`Field5` = 0 or
`TABLE_B`.`Field5` = 6) AND
(`TABLE_B`.`Field6` is NULL) AND
(`TABLE_B`.`Field7` is NULL)
と書きます。

質問者さんが書いたWHERE文は

Field1は必ずNULL
かつ
Field2は値が1~14のどれか。それ以外にはマッチしない
または
Field3は0か3のどちらかにマッチ。
または
Field4は2以外にマッチ。
または
Field4は3以外にマッチ。
または
Field4は4以外にマッチ。
または
Field4は8以外にマッチ。
または
Field5は0,6のどちらかいにマッチ。
または
Field6はNULLを抽出
または
Field7はNULLを抽出
に一致する。

特に
Field4は2以外にマッチ。
または
Field4は3以外にマッチ。
または
Field4は4以外にマッチ。
または
Field4は8以外にマッチ。
は「無条件」と同一になります。何が来ても条件が真になるのを理解できますか?

また、各フィールドの条件を「または」で連結しているので、フィールド条件を1~3から1~5に増やすと「または」により条件が広がるので、一致レコードが増えます。

「1が赤」かつ「2が白」または「3が青」(フィールド条件が1~3)
から
「1が赤」かつ「2が白」または「3が青」または「4が黒」または「5が緑」(フィールド条件が1~5)
に変えれば、『「4が黒」または「5が緑」』の条件に一致するレコードが増えます。

「4が黒」の物が無条件に増え、「5が緑」の物が無条件に増えます。なので
>Field1~Field3まで抽出を
>かけた時に、1万件だったのが、Field1~Field5までを含めると、1万2000件に
>なってしまいます。
となるのが「当たり前」です。

ORは、条件を「絞り込む」のではなく、条件を「緩和」させます。

条件を絞り込むにはANDを使います。

なお
「2でも3でも4でも8でもない」

(`TABLE_B`.`Field4` <> 2 or
`TABLE_B`.`Field4` <> 3 or
`TABLE_B`.`Field4` <> 4 or
`TABLE_B`.`Field4` <> 8)
ではありません。

「2でも3でも4でも8でもない」

「2でない、かつ、3でない、かつ、4でない、かつ、8でない」
だと言う事を理解しましょう。

もし
「2でない、または、3でない、または、4でない、または、8でない」
と書くと、これは
「何でもよい」
と言う意味になります。

1がくると
「2でないは真、または、3でないは真、または、4でないは真、または、8でないは真」
で、全体は真になります。

2がくると
「2でないは偽、または、3でないは真、または、4でないは真、または、8でないは真」
で、全体は真になります。

3がくると
「2でないは真、または、3でないは偽、または、4でないは真、または、8でないは真」
で、全体は真になります。

4がくると
「2でないは真、または、3でないは真、または、4でないは偽、または、8でないは真」
で、全体は真になります。

どうです?「何が来ても無条件に真になる」のが判りますか?

投稿日時 - 2011-07-14 11:53:08

お礼

ありがとうございます!大変よく理解できました!感謝です!

投稿日時 - 2011-07-23 11:02:58

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

基本はANDがORより強い・・・
今回ORで書かれているところも実はANDのような気がします。

WHERE 1
AND Field1 IS NULL
AND Field2 BETWEEN 1 AND 14
AND Field3 IN(0,3)
AND NOT (Field4 IN (2,3,4,8))
AND Field5 IN(0,6)
AND Field6 IS NULL
AND Field7 IS NULL

投稿日時 - 2011-07-14 12:46:12

お礼

ありがとうございます!大変よく理解できました!感謝です!

投稿日時 - 2011-07-23 11:03:09

ANo.1

書いてあるWHERE句からすると

Field1は必ずNULL
かつ
Field2は値が1~14のどれか。それ以外にはマッチしない
または
Field3は0か3のどちらかにマッチ。
または
Field4は2,3,4,8に以外にマッチ。
または
Field5は0,6のどちらかいにマッチ。
または
Field6はNULLを抽出
または
Field7はNULLを抽出

って感じになりますけどあってますか?
Field1とField6、7の違いも良くわかりませんが、Field1には全レコードで必ずNULLが入っていてField6、7はいろいろ入ってるけどNULLのものを抽出するってことでしょうか?

WHERE
`TABLE_A`.`Field1` IS NULL AND
(`TABLE_B`.`Field2` = 1 OR
・・・ OR
 `TABLE_B`.`Field2` = 14) AND
(`TABLE_B`.`Field3` = 0 OR
`TABLE_B`.`Field3` = 3) AND
(`TABLE_B`.`Field4` <> 2 AND
`TABLE_B`.`Field4` <> 3 AND
`TABLE_B`.`Field4` <> 4 AND
`TABLE_B`.`Field4` <> 8) AND
(`TABLE_B`.`Field5` = 0 OR
`TABLE_B`.`Field5` = 6) AND
`TABLE_B`.`Field6` is NULL AND
`TABLE_B`.`Field7` is NULL

こんな感じじゃないでしょうか。
・・・のところは適当にいれてください。

投稿日時 - 2011-07-14 11:37:55

お礼

ありがとうございます!大変よく理解できました!感謝です!

投稿日時 - 2011-07-23 11:03:02