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

このQ&Aのポイント
  • 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句で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

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

  • ベストアンサー
  • chie65535
  • ベストアンサー率43% (8522/19371)
回答No.2

条件が 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でないは真」 で、全体は真になります。 どうです?「何が来ても無条件に真になる」のが判りますか?

mellow91
質問者

お礼

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

その他の回答 (2)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.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

mellow91
質問者

お礼

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

  • ponta1971
  • ベストアンサー率30% (361/1191)
回答No.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 こんな感じじゃないでしょうか。 ・・・のところは適当にいれてください。

mellow91
質問者

お礼

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

関連するQ&A

  • Where句のNot条件をAnd条件にしたい!

    現在where句でNot(A is not null and B is not null)という条件をしているSQLがあるのですが、この表現をNot句を使わずに表現するとなるとどのように表現したら良いのでしょうか? SQL以前の問題だと思うのですが、上手く表現できずに件数が合わずに困っています。どなたか助言お願い致します。

  • SQL WHERE句 分岐?

    SQL Server 2005 を使っております。 WHERE句の分岐といいますか、記述の方法がわからないのですが、下記がその部分になります。 下記のコードを実行すると、都道府県、血液型、両方に何かしらのデータが入っているものしか抽出してきません。都道府県、血液型、どちらかの値がNullの場合でも、どちらかの条件が合致していれば、抽出したいのですが、どう記述すればよろしいでしょうか? 下記のコードが Null = Null を認識していれば このコードでも抽出してくるんでしょうが、 Null = Null だと抽出しないんですね。 何卒よろしくお願いいたします。 WHERE (IsNull(@A,dbo.テスト.都道府県) = dbo.テスト.都道府県) AND (IsNull(@B,dbo.テスト.血液型) = dbo.テスト.血液型

  • SQLのWHERE句を条件によって追加したい

    SQLのWHERE句にパラメータで渡された値がnullでない場合は条件に 含めるようにしたいのですが、書き方が分かりません。 CASEを使って書いてもエラーになってしまいます。 SELECT 項目1 ,項目2 FROM テーブル WHERE 条件1 = パラメータ1 AND 条件2 = パラメータ2 -- パラメータ3がnullでない場合は下記条件を付けたい AND 条件3 = パラメータ3 使っているのはpostgresqlです。 よろしくお願いします。

  • なぜ、WHERE句とHAVING句があるのか?

    なぜ、WHERE句とHAVING句があるのか? SQLを学んでいる時に、疑問に思ったことがあります。 それは、「なぜ、WHERE句とHAVING句があるのか?」ということです。 この2つは、 ・WHERE句 → 表から取り出す行の条件を指定 ・GROUP BY句 → グループ化した結果から取り出す行の条件を指定 という違いがあることは分かっています。 ですが、おなじ「行のかたまりに対する抽出条件」を指定しているのに、 なぜ、わざわざ2つに分ける必要があったのでしょうか? 分けないと不都合が生じるのでしょうか。 もし、明瞭簡潔に説明できる方がいらっしゃいましたら、教えていただけないでしょうか。

  • sql文のwhere句について

    <環境>sqlserver SQLでパラメータが空白であれば全件取得、パラメータに値が設定されている場合には 条件にHITするデータを抽出したいのですが、一本のクエリで抽出することができるのでしょうか? 空白時パラメータは以下のとおり入ってきます。 @no="" …完全一致 @name="%%" …部分一致 例) SELECT * FROM テーブル WHERE (NO = @no) and ((@name IS NULL) OR (@name IS NOT NULL) AND (NAME LIKE @name)) NAMEは上記クエリにて取得できています。 NOのところはどのようにすればよいでしょうか?

  • 同じ値が存在しないレコードの抽出方法について

    下記のテーブルの中で、 b_tableテーブルのidフィールドの値が1つしかない(重複していない)フィールドを抽出したいと思います(この場合ですが、3002と3004を抽出したいです)。 その際、抽出条件を下記の【※※※ここに記述を追加※※※】に記述することで実現したいと思ったのですが、その場合どのようなsql文を書けば良いか分かりませんでした。 その為、このような場合、どのようなsql文を書けば良いかご存知の方がいらっしゃいましたら、ご教示の程、よろしくお願いします。 なお、【※※※ここに記述を追加※※※】に記述を追加したい理由ですが、既存のSQL文にこの条件を追加したいのですが、WHERE以前は別の部分に記述されており、その部分が変更できない為です。 なお、下記のWHERE以前の記述はあくまでサンプルであり、重複していないフィールドを抽出するSQL文と直接関係のない記述でしたら、変更していただいても大丈夫かもしれません(この点曖昧で申し訳ございません。移植元の記述ではテーブルを連結しているように見受けられたため、連結の仕方が多少変わる分には問題ないのかなと思っています。この点については実際にソースをご提示いただければ、それを元に移植させていただいた上で、ご回答差し上げたいと思います)。 ■SQL文 SELECT a.id FROM `a_table` AS a LEFT JOIN `b_table` AS b ON a.id = b.id WHERE 【※※※ここに記述を追加※※※】 ■a_tableテーブル CREATE TABLE IF NOT EXISTS `a_table` ( `auto_id` int(3) NOT NULL, `id` varchar(4) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `a_table` (`auto_id`, `id`) VALUES (101, '3001'), (102, '3002'), (103, '3003'), (104, '3004'); ■b_tableテーブル CREATE TABLE IF NOT EXISTS `b_table` ( `auto_id` int(3) NOT NULL, `id` varchar(4) NOT NULL, `no` varchar(1) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO `b_table` (`auto_id`, `id`, `no`) VALUES (101, '3001', '1'), (102, '3001', '2'), (103, '3001', '3'), (104, '3002', '2'), (105, '3003', '1'), (106, '3003', '2'), (107, '3004', '1'); 以上、よろしくお願いします。

    • ベストアンサー
    • MySQL
  • WHERE レコードが抽出されない

    ADOでSQL文を作ってるのですが WHERE句がうまくできません。 rs.Open "T_テーブル", cn, adOpenKeyset, adLockOptimistic rs.Filter = "URL like '#*'" なら、うまくいくのですが、 Filterを使うのをやめて、WHEREに書きかえると、エラーにはならないのですが 取得レコードが0件になります。 rs.Open "T_テーブル WHERE [URL] like '#*';", cn, adOpenKeyset, adLockOptimistic も rs.Open "T_テーブル WHERE URL like '#*';", cn, adOpenKeyset, adLockOptimistic も、0件が返ります。 何がおかしいのでしょうか? URLフィールドで、#で始まるレコードを抽出したいです。

  • WHERE句の中でCASE句

    区分が1の時にステータス0,1,2のもの、区分が1以外の場合はステータス0,1のものを抽出、というSQLを書きたいのですが、 WHERE句の中に (CASE Kbn WHEN '1' THEN Status in('0','1','2') ELSE Status in('0','1') END) とするとエラーとなりました。 このような場合、WHERE句の中にCASE句で実現は不可能でしょうか? 一応以下のようにすれば期待通りの内容が抽出できるのですが、美しくないなあと。 ((Kbn = '1' AND Status in('0','1','2')) OR (Kbn != '1' AND Status in('0','1'))) 何か他にいい手がありますでしょうか。

  • Oracle SQLの、where句内の条件文について教えてください。

    Oracle SQLの、where句内の条件文について教えてください。 下記SQLの(1)と(2)の記述文を教えてください。 (1)例:owner = sys,admin ownerがsysまたは、adminを抽出 (2)例:column_name = '*aaa*' column_nameに「aaa」が含まれているデータ SELECT owner, table_name,column_name FROM all_tab_columns WHERE (1)(Ownerを複数指定)   and (2)(column_nameに、●●が含まれるデータ)

  • 特定条件でWHERE句の条件を変更したい

    @jouken int @sql varchar(MAX) @select varchar(MAX) @where varchar(MAX) set @select = 'select * from table1' set @where = ' where case when @jouken = 0 then 'field1 = 1' when @jouken = 1 then 'field1 = 1 or field2 = 1' when @jouken = 2 then 'field1 = 1 or field2 = 1 or field3 = 1' end ' set @sql=@select+@where exec(@sql) 上記のような文字列の組み合わせでの作成でやりたいことはできたのですが、 こちらを直接SQLの中でやりたいのです。 以下の文は機能しません。 select * from table1 where case when @jouken = 0 then field1 = 1 when @jouken = 1 then field1 = 1 or field2 = 1 when @jouken = 2 then field1 = 1 or field2 = 1 or field3 = 1 end ご教授の程、よろしくお願い致します