- 締切済み
否定条件回避
お世話になります。 エラーデータチェックの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))) 後々考えたらやっぱり抜けるところがある気がします・・・ どなたかご教授いただけると助かります。 よろしくお願いします。
- みんなの回答 (2)
- 専門家の回答
みんなの回答
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
>提示していただいた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 ; ついでに、絞り込み条件が片側しか書いてないので、少なく絞り込まれる可能性があるので、見直してます。
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
質問に書かれた内容が一部理解できないけれど・・ 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句に否定条件はちょっと厳しいです。 結局のところ、全件対象に外部結合する必要があるのであれば、コストを気にしても意味がないと思いますが、 少しでも、コストを気にするのであれば、外部結合をしない/減らす努力が必要でしょう。
補足
koroさん、返信遅れして、すみません。 提示していただいたSQLだと、余計なデータが取れてしまいます。 >質問に書かれた内容が一部理解できないけれど どの部分でしょうか。 2つのテーブルの各項目値のが違っているデータを取りたいです。 ただし、A.aとB.aが一致であれば、A.bやA.cが値が入っていて、 B.bやB.cがNullのときは、取得対象外です。 (↑テーブルA、B結合して、1行目のレコードのように)