激凹みから立ち直る方法

タイトルのように、Aテーブルにあるが、Bテーブルまたは、Cテーブルにあれば抽出しないWhere文を作成したいのですが、ご教授ください。尚、Dテーブルより名称を抽出したいです。

 select a.項目1,a.項目2,d.名称 from Aテーブル a,Bテーブル b,Cテーブル c,Dテーブル d where a.条件1 = 1 and d.項目1 = a.項目1 and d.項目2 = a.項目2 NOT((b.項目1 = a.項目1 and b.項目2 = a.項目2 and 条件2 = 0) or (c.項目1 = a.項目1 and c.項目2 = a.項目2 and 条件2 = 0))

 上のselect文ではダメでしょうか?

A 回答 (1件)

結論から言うと、質問文のSQLでは抽出できません。


理由ですが、Aテーブルにあって、BテーブルまたはCテーブルに無いような条件の場合はテーブルの結合条件として、外部結合を使う必要がありますが、質問文のSQLでは内部結合を使っています。内部結合を使うと、結合したテーブルの何れかにデータが欠如していると、該当のAテーブルのレコード情報は抽出されません。しかし、外部結合を使えば、Aテーブルのみに存在する情報も抽出可能です。

一般に、FROM句にテーブル名を並べるか、キーワードINNER JOINを使った場合は内部結合(ただし、OracleではFROM句にテーブル名を並べても外部結合として扱う記述方法が存在します。)、LEFT JOINもしくはRIGHT JOINを使うと外部結合となります。

質問文のSQLからはそれぞれのテーブルの結合条件が不明なため、そのまま動作するSQLを回答することはできませんが、仮にテーブルA〜Dのキー項目が項目1で、全テーブルの結合条件が項目1の場合、以下のようなSQLで結合できます。

SELECT a.項目1, d.名称
FROM Aテーブル a
LEFT JOIN Bテーブル ON a.項目1 = b.項目1
LEFT JOIN Cテーブル ON a.項目1 = c.項目1
LEFT JOIN Dテーブル ON a.項目1 = d.項目1
WHERE b.項目1 IS NULL OR c.項目1 IS NULL

LEFT JOINをベースに外部結合(LEFT JOIN)しているので、Bテーブル、またはCテーブルに該当の情報がなくても情報が抽出されます。また、Aテーブルに情報が存在し、Bテーブルに情報が存在しない場合、Bテーブルに関連する情報は全てNULLになるため「b.項目1 IS NULL」とすることで、「Aテーブルに存在し、Bテーブルに存在しない」データを抽出できます。同様にして「c.項目1 IS NULL」とすると、Cテーブルには存在しない情報が抽出できます。

なお、SQLは使用するSQLサーバの種類やバージョンによって動いたり、動かなかったりします。質問するときは使用するSQLサーバの種類とバージョン(Oracle 11g、Postgresql 9.6など)も記載していただけると、より正確なSQLを回答できます。
    • good
    • 0
この回答へのお礼

さっそくのご回答ありがとうございます。
まだ初心者なので、SQLサーバの種類やバージョンは覚えておりません。済みません。

項目1はキー項目ではないので、

SELECT a.項目1,a.項目2, d.名称
FROM Aテーブル a
LEFT JOIN Bテーブル ON a.項目1 = b.項目1 and a.項目2 = b.項目2
LEFT JOIN Cテーブル ON a.項目1 = c.項目1 and a.項目2 = b.項目2
LEFT JOIN Dテーブル ON a.項目1 = d.項目1 and a.項目2 = b.項目2
WHERE b.項目1 IS NULL OR c.項目1 IS NULL

以上の書き方でもよろしいでしょうか?

お礼日時:2016/10/23 14:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


おすすめ情報