• 締切済み

否定条件回避

お世話になります。 エラーデータチェックのSQLを作成していますが、 難航しています。 バージョン:Oracle10.2 Aテーブル  a1 b1 c1 a2 b2 a3 b3 c3    Bテーブル a1 b1 a2 gg a3 上のように2つのテーブルがあるとします。 2つのテーブルの各項目がエラーあるかどうかをチェックします。 上の場合は2行目のレコードがエラーとし、取得したいです。 結合条件はa,b,c。ただどれもNULLの場合があって、3つのうち必ずどれかが値が入っています。A.a1とB.a1があっていれば、正常データとします。 大量データため、WHERE句に否定条件はちょっと厳しいです。 自分が考えたのはMINUS 例:SELECT * FROM Aテーブル LEFT JOIN Bテーブル   ON (A.a = B.a OR A.b = B.b OR A.c = B.c) MINUS SELECT * FROM Aテーブル LEFT JOIN Bテーブル ((ON A.a = B.a OR (A.a IS NULL OR B.a IS NULL)) (AND A.b = B.b OR (A.b IS NULL OR B.b IS NULL)) (AND A.c = B.c OR (A.c IS NULL OR B.c IS NULL))) 後々考えたらやっぱり抜けるところがある気がします・・・ どなたかご教授いただけると助かります。 よろしくお願いします。

  • Oracle
  • 回答数2
  • ありがとう数1

みんなの回答

回答No.2

>提示していただいたSQLだと、余計なデータが取れてしまいます。 外部結合の条件が悪いんでしょうね。 たぶん、適切な結合条件は、以下のような感じだと思います。 SELECT * FROM Aテーブル A LEFT JOIN Bテーブル B ON ( (A.a=B.a or A.a is null or B.a s null) and (A.b=B.b or A.b is null or B.b s null) and (A.c=B.c or A.c is null or B.c s null) ) WHERE decode(A.a,null,0,B,a,0,1)=1 or decode(B.a,null,0,A,a,0,1)=1 or decode(A.b,null,0,B,b,0,1)=1 or decode(B.b,null,0,A,b,0,1)=1 or decode(A.c,null,0,B,c,0,1)=1 or decode(B.c,null,0,A,c,0,1)=1 ; ついでに、絞り込み条件が片側しか書いてないので、少なく絞り込まれる可能性があるので、見直してます。

回答No.1

質問に書かれた内容が一部理解できないけれど・・ SELECT * FROM Aテーブル A LEFT JOIN Bテーブル B ON (A.a=B.a OR A.b=B.b OR A.c=B.c) WHERE decode(A.a,null,0,B,a,0,1)=1 or decode(A.b,null,0,B,b,0,1)=1 or decode(A.c,null,0,B,c,0,1)=1 ; とかで良いんじゃないですかね。 例)に書かれたSQLが2度の外部結合を行っていますが、それに比べれば、格段に合理的な気がします。 (質問に対する私の理解が正しければですけど・・) >大量データため、WHERE句に否定条件はちょっと厳しいです。 結局のところ、全件対象に外部結合する必要があるのであれば、コストを気にしても意味がないと思いますが、 少しでも、コストを気にするのであれば、外部結合をしない/減らす努力が必要でしょう。

sinomori
質問者

補足

koroさん、返信遅れして、すみません。 提示していただいたSQLだと、余計なデータが取れてしまいます。 >質問に書かれた内容が一部理解できないけれど どの部分でしょうか。 2つのテーブルの各項目値のが違っているデータを取りたいです。 ただし、A.aとB.aが一致であれば、A.bやA.cが値が入っていて、 B.bやB.cがNullのときは、取得対象外です。 (↑テーブルA、B結合して、1行目のレコードのように)

関連するQ&A

  • 意味は同じはずなのに結果が違います。

    SELECT * FROM テーブルA LEFT OUTER JOIN ( SELECT * FROM テーブルB WHERE テーブルB.列X IS NOT NULL) as テーブルB ON テーブルA.列A = テーブルB.列A SELECT * FROM テーブルA LEFT OUTER JOIN テーブルB ON テーブルA.列A = テーブルB.列A WHERE テーブルB.列X IS NOT NULL 上のSQLも下の同じ事をしてると思うのですが 上では検索結果が10件出た場合 下では0件になってしまいます。 SQL自体シンプルで間違っていないと思うのですがなぜでしょうか?

  • joinの入れ子について

    A(contenthead)をベースにAがBに存在せずかつCに存在しないデータをを作りたいのですが上手く行きません。以下を実行すると SELECT a.contentid, b.contentid, d.contentid From (contenthead as a LEFT JOIN group as b on a.contentid = b.contentid) left join (contenthead as c LEFT JOIN ouser as d on c.contentid = d.contentid) on a.contentid = c.contentid 表示結果は 1、1、NULL 2、NULL、Null 3、NULL、3 4、NUL、4 と出て来ます。従って両方にないのは2だけということになります。 実際のデータもそうなっています。 そこで、 WHERE ((b. contentid) is null) and ((d. contentid) is null)を上記SQLに付加するとなぜか 2、NULL、Null 3、NULL、null 4、NUL、NULL と表示されます。 教えて頂きたいことお分かり戴けますでしょうか宜しく御願い致します。

    • ベストアンサー
    • MySQL
  • 3テーブル外部結合方法について

    3つのテーブルを外部結合したいのですが・・・、 こんがらがってしまいました。 A,B,Cの3テーブルがあり、A,B,Cの順に外部結合 (LEFT OUTER JOIN)したいのですが、 A,BのテーブルについてはWhere句の条件指定が 必要です。 Select From (Select AA.a From A AA Where b = xxxx) BB Left Outer Join (Select CC.b From B CC Where c = eeee and BB.a = CC.b) On ???? こんな感じでつまづいてしまいました・・・

  • 複数JOINしているとCOUNTが正しく取得できな

    LAMP環境で開発をしています。 SQL文でCOUNTを求める際に、まとめて結果を求めようとして上手く行きません。 状況としては以下です。 テーブルdはidをkeyにa,b,c3つのテーブルとjoinしています。 id = 1の場合、テーブルa,b,cにマッチするレコードがそれぞれに4個、1個、0個あります。 ひとつひとつを SELECT COUNT(CASE WHEN a.name IS null THEN 1 ELSE null END) as a_count FROM d INNER JOIN a ON a.id = d.id WHERE d.id = 1 として結果を求めると4,1,0と出るのですが、まとめて SELECT COUNT(CASE WHEN a.name IS null THEN 1 ELSE null END) as a_count, COUNT(CASE WHEN b.name IS null THEN 1 ELSE null END) as b_count, COUNT(CASE WHEN c.name IS null THEN 1 ELSE null END) as c_count FROM d INNER JOIN a ON a.id = d.id INNER JOIN b ON b.id = d.id INNER JOIN c ON c.id = d.id WHERE d.id = 1 とすると28,5,0という値が返されます。 どのように書けば正しい4,1,0を得られるのでしょうか? よろしくお願いします。

    • ベストアンサー
    • MySQL
  • ACCESS 追加クエリ

    二つのテーブルがあります。テーブルAには10個のデータ(A-J)、Bには5個のデータ(A-E)が記載されています。 BにはないAのデータ(F,G,H,I,J)をBに追加するクエリを作りましたが、『出力先’DATA'が重複しています。』というエラーが出ます。 二つのテーブルの差分を取っているためこのようなことになるのですが、回避する方法を教えてください。 クエリ INSERT INTO テーブルB ( DATA_B, DATA_B ) SELECT [テーブルA].DATA_A, [テーブルB].DATA_B FROM テーブルA LEFT JOIN テーブルB ON [テーブルA].[DATA_A] = [テーブルB].[DATA_B] WHERE ((([テーブルB].DATA_B) Is Null));

  • LEFT JOIN の結合結果について

    お世話になります。 ”SELECT Aテーブル.* Bテーブル.*  FROM Aテーブル LEFT JOIN Bテーブル ON Aテーブル.KEY = Bテーブル.KEY”を 行った場合、Aテーブルにしか存在しないデータのBテーブル側の値は常にNULLに なるようなのですが、この場合ゼロを固定に設定することは出来ないでしょうか? よろしくお願いします。 ※ORACLE 9i、PL/SQL上での処理を考えています

  • テーブル結合について、下記SQLをANSI結合の書き方で表したい。

    テーブル結合について、下記SQLをANSI結合の書き方で表したい。 select * from (select key from A union select key from B union select key from C) X, A,B,C where X.key=A.key(+) and X.key=B.key(+) and X.key=C.key(+) このSQLをANSI結合の記述で書きたいのですが、 (+)での結合文になれておらず試行錯誤しております。 下記のようなのかなとは模索しておりますが、 手元に実行環境がなくわかりません。 また、要所気付く点などありましたら、ご指摘願います。 select A.*, B.*, C.* from (select key from A union select key from B union select key from C) X, LEFT JOIN A ON X.key=A.key LEFT JOIN B ON X.key=B.key LEFT JOIN C ON X.key=C.key

  • 複数テーブルを結合するには?

    OS:WINDOWSXP SP2 ORACLE:Oracle9i Enterprise Edition Release 9.2.0.1.0 A, B, Cというテーブルがあるとします。 それぞれのテーブルには XXカラムと YYカラムがあるとします。 2つのテーブルを結合させるには、以下のSQL文を記述すれば良いと考えています。 SELECT A.*,B.* FROM A JOIN B ON A.XX = B.XX 3つのテーブルを結合するには、以下のSQL文を記述しています。 SELECT A.*,B.*,C.* FROM A JOIN B ON A.XX = B.XX JOIN C ON A.XX = C.XX 但し、この記述方法でいきますと、Cテーブルを右側外部結合に指定した場合のみ、 ORA-00904 "C" 無効な識別子です。 というエラーメッセージが表示されます。 SELECT A.*,B.*,C.* FROM A JOIN B ON A.XX = B.XX RIGHT OUTER JOIN C (←LEFT OUTER、FULL OUTER)なら通ります) ON A.XX = C.XX 何故、右側外部結合のみ不正となるのか不明であり、解決策が見つかりません。 複数のテーブルを結合する為のSQL文の記述方法を教えて頂けますでしょうか?

  • LEFT JOINが2つあるSQL文でANDの意味

    ■下記SQL文の意味を教えてください SELECT a.*, b.being_name FROM alive a  LEFT JOIN being b ON a.hoge_id = b.id  LEFT JOIN call c ON c.call_id = a.hoge_id   AND f.hoge_id = 12  WHERE f.hoge_id = 12 OR b.id = 12 ※12の部分は動的に切り替わります ・LEFT JOINが2つあるので、3つのテーブルを結合しているのでしょうか? ・左テーブルは「alive a」で、この右側に2つのテーブルが結合している、という認識でよいでしょうか? >SELECT フィールド名 FROM テーブル名 WHERE 条件式1 AND 条件式2 >「AND」は2つの条件式の論理積 ・上記内容をネットで見かけたのですが、「AND」は、「WHERE」の前に来てもいいのでしょうか? それともこのSQLの「AND」は違う使い方をしているのでしょうか? 何か、LEFT JOINに関係しているのでしょうか?

    • ベストアンサー
    • MySQL
  • joinの場合のテーブル名の別名の使用方法

    select * from table1 a,table2 b where a.field1=b.field1; とできますが select * from table1 as a left join table2 as b on a.field1=b.field1; とできません。 joinの場合にテーブル名の別名を使う方法を教えてください