• ベストアンサー

SQL初心者なので教えてください。

毎度ここにお世話になっております。 売上詳細という表の中にNOとSYOHIN_CDの列があるとします。 Noは1~10まであり、SYOHIN_NAMEにはNo6の列だけ文字が入っています。 ここで、No1~N5はSHYOHIN_NAMEはNULLで、No6~No10のいずれかのSYOHIN_NAMEに文字が入っている物を検索するにはどうしたらいいでしょう? SELECT * FROM hanbai.売上 AA where EXISTS (select * from hanbai.売上詳細 BB where BB.NO between 1 and 5 and SYOHIN_NAME is null and BB.NO between 6 and 10 and SYOHIN_NAME is not null); 構文間違っているので表示されませんが・・・ちゃんと表示されるSQLを教えてください。お願いします。オラクルです。 説明がおかしくてわかりづらいと思いますが、補足しますのでよろしくおねがいします。

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

  • ベストアンサー
noname#4564
noname#4564
回答No.1

  まず、論理AND/OR演算子の意味 ( 概念レベルでの ) と用法を正しく理解しましょう。 一例ですが、 WHERE ID = 1 OR ID = 2 だと、「IDが1、または2」のレコードが抽出されますが、 WHERE ID = 1 AND ID = 2 「IDが1であり、かつ2でもある」条件となり、該当するレコードは論理的に存在し得ません。 ※ 概念が抽象的で理解しにくい場合は、   WHERE 消息 = '生存' OR 性別 = '死亡'   WHERE 消息 = '生存' AND 性別 = '死亡'   または、   WHERE 性別 = '男' OR 性別 = '女'   WHERE 性別 = '男' AND 性別 = '女'   で考えてみてください。 上記の内容が理解できたら、次に演算子の結合優先順位は括弧の使い方で変化することを理解しましょう。 2 + 3 × 4 と (2 + 3) × 4 はおなじではありません。(2 + 3 × 4 = 14 ですが、(2 + 3) × 4 = 20 となります) ANDとORが入り混じった条件式では、結合順序を明確にするため、(必要の有無に関わらず)括弧を付けるのが一般的です。  

mitutoshi
質問者

お礼

解決しました、ありがとうございました。

mitutoshi
質問者

補足

優先順位をつけるために()をつけるのはわかりました。 なので、 SELECT * FROM hanbai.売上 AA where exists (select * from 売上詳細 BB where ((BB.NO between 1 and 5) and (BB.syohin_name is null)) and ((BB.NO between 6 and 10) and (BB.syohin_name is not null)) and AA.uriage_no = BB.uriage_no); でやったのですが、結果がすべてでてきてよくわからなく なりました。 NOの1~5のsyohin_nameがnullで、かつNOの6~10のsyohin_nameがいずれか文字が入ってれば結果を渡したいのだからすべて『and』でよろしいんですよね?そのところがよくわからなくなってきたのでどうかよろしくおねがいします。

その他の回答 (2)

  • PAPA0427
  • ベストアンサー率22% (559/2488)
回答No.3

つまり、No.が1~5までの時は、syohin_nameはnullなんですね。(nullでも良いとnullだ、というのは違います。) No.が6~10の時は、syohin_nameはnullであってはいけないんですよね。 SELECT * FROM hanbai.売上 AA where exists (select * from 売上詳細 BB where ((BB.NO between 1 and 5) and (BB.syohin_name is null)) or ((BB.NO between 6 and 10) and (BB.syohin_name is not null)) and AA.uriage_no = BB.uriage_no); >ここで、No1~N5はSHYOHIN_NAMEはNULLで、No6~No10のいずれかのSYOHIN_NAMEに文字>が入っている物を検索するにはどうしたらいいでしょう? という事は、 No. syouhin_name 1 null 2 null 3 null 4 null 5 null 6 ABCDEFl 7 null 8 null 9 null 10 null とイメージしてよいですか? これだと、別にNo.は関係ない気がしますが・・・。 SELECT * FROM 売上 AA,売上明細 BB WHERE AA.uriage_no = BB.uriage_no AND BB.syouhin_name is not null; 検索できるはずですが、はずしていたらごめんなさい。 ただ、もう少しおやりになりたい事を具体的にかかれた方が、回答者も助かりますが。お願いします。

mitutoshi
質問者

お礼

解決しました。ありがとうございました。

mitutoshi
質問者

補足

説明があやふやですみません。 えっと、上の表はそのままあっています。その状態だけ表示させたいです。1~5にはNULLが必ず入ってて、6~10は文字が入る(表示させたい列にはほとんどの場合、NO、6に文字が入ってます。) で表示させたくないのは、1つ目が、NO1~5までにNAMEの列に文字がはいっている。そしてNO6~10までにもNAMEに文字がはいっている。2つ目がNO1~5までにNAMEはすべてNULLが入っていて、そしてNO5~10までにNAMEに文字が入っている。です。 自分で試したのは、 SELECT * FROM hanbai.売上 AA where exists (select * from 売上詳細 BB where ((BB.NO between 1 and 5) and (BB.syohin_name is null)) and ((BB.NO between 6 and 10) and (BB.syohin_name is not null)) and AA.uriage_no = BB.uriage_no); です。これでNO1~5までがnameがnullでNO6~10まではNAMEがいづれか文字が入っていて、売上のuriage_noと売上詳細のuriage_noが同じ値のみ表示させるからこれで大丈夫だと思ったのですが、表示させたい物まで表示されません。

  • bin-chan
  • ベストアンサー率33% (1403/4213)
回答No.2

> ここで、No1~N5はSHYOHIN_NAMEはNULLで、No6~No10のいずれかのSYOHIN_NAMEに文字が入っている物を検索するにはどうしたらいいでしょう? この文はデータの現状の説明なのでしょうか? それとも出力の条件なのでしょうか? No.にかかわらず、SYOHIN_NAMEに文字がある(Not NULL) なら、以下の文ではいかがですか? select * from hanbai.売上 aa where AA.uriage_no in ( select BB.uriage_no from 売上詳細 BB where bb.SYOHIN_NAME is not null );

mitutoshi
質問者

お礼

解決しました、ありがとうございました。

関連するQ&A