性格悪い人が優勝

ご存知の方がおられましたら、教えて下さい。
下記のように、親テーブルと親子を管理するための親子管理テーブルがあります。
条件として、CD1の1が指定された時、親テーブルよりNOが2のレコードと(これは親子関係がないレコード)
親子関係のレコードの親レコードであるNOが1のレコードと子レコードであるNOが11の3レコード
を1つのSQL文で取得したいのですが、可能でしょうか?

ご存知の方がおられましたら、ご教授のほどよろしくお願い致します。

親テーブル(OYA_TBL)
NO,BN1,CD1
-------------
1,4,NULL
2,NULL,1
3,NULL,NULL
11,4,1
12,4,2
13,4,NULL


親子管理テーブル(OYA_KO_TBL)
GOODS_NO,PACK_GOODS_NO
-------------
1,11
1,12
1,13



[取得結果]
NO,BN1,CD1
-------------
1,4,NULL
2,NULL,1
11,4,1

A 回答 (3件)

>親テーブルよりNOが2のレコードと(これは親子関係がないレコード)


>親子関係のレコードの親レコードであるNOが1のレコードのみを取得したい場合(子レコードは不要)、どうすればよいでしょうか?

先ほどのSQLに、条件を追加すると下記。
少し、無駄がありそうですね。

SELECT OYA_TBL.*
FROM OYA_TBL
WHERE
(
OYA_TBL.CD1 = 1
OR
EXISTS (
SELECT Y.GOODS_NO
FROM OYA_TBL X INNER JOIN OYA_KO_TBL Y
ON (X.NO = Y.PACK_GOODS_NO)
WHERE (X.CD1 = 1) AND (Y.GOODS_NO = OYA_TBL.NO)
)
)
AND
NOT EXISTS (
SELECT Z.PACK_GOODS_NO
FROM OYA_KO_TBL Z
WHERE (Z.PACK_GOODS_NO = OYA_TBL.NO)
);

------------------------------------------------------------
下記の方が良いかな?
条件を分けて、UNIONで結合。

SELECT OYA_TBL.*
FROM OYA_TBL, OYA_KO_TBL X, OYA_TBL Y
WHERE (OYA_TBL.NO = X.GOODS_NO)
AND (X.PACK_GOODS_NO = Y.NO)
AND (Y.CD1 = 1)

UNION

SELECT OYA_TBL.*
FROM OYA_TBL LEFT JOIN OYA_KO_TBL B
ON OYA_TBL.NO = B.PACK_GOODS_NO
WHERE (OYA_TBL.CD1 =1)
AND (B.PACK_GOODS_NO Is Null);

------------------------------------------------------------
更に別回答。
LEFT JOIN の結合をメインに。

SELECT OYA_TBL.*
FROM
(
(
OYA_TBL LEFT JOIN OYA_KO_TBL X
ON OYA_TBL.NO = X.GOODS_NO
) LEFT JOIN OYA_TBL Y
ON X.PACK_GOODS_NO = Y.NO
) LEFT JOIN OYA_KO_TBL Z
ON OYA_TBL.NO = Z.PACK_GOODS_NO
WHERE ( (OYA_TBL.CD1 = 1) AND (Z.GOODS_NO Is Null) ) OR (Y.CD1 = 1);

------------------------------------------------------------
ついでに、最初の質問の別解。
サブクエリをなくして、テーブル結合で。

SELECT X.*
FROM
(
OYA_TBL X LEFT JOIN OYA_KO_TBL Y
ON X.NO = Y.GOODS_NO
) LEFT JOIN OYA_TBL Z
ON Y.PACK_GOODS_NO = Z.NO
WHERE (X.CD1 = 1) OR (Z.CD1 = 1);

------------------------------------------------------------
全てAccess2000で動作確認。
文法の違いが分からないので、
Oracleでも動きそうなものを選んで下さい。
    • good
    • 0
この回答へのお礼

色々とご教授下さり、ありがとうございました。
CD1の条件が必要ない場合もあるようで、その場合は親子関係のレコードを全て抽出する必要があり、そうすると最初に教えていただいたexistを使ったSQLだと、親レコードしか取得できなかったので、
LEFT JOIN の結合をメインにしたSQL文を採用させていただきました。
僕自身、あまりexist条件って使った事がなかったので、勉強になりました。本当に、助かりました。ありがとうございました。

お礼日時:2007/12/26 00:14

SELECT OYA_TBL.*


FROM OYA_TBL
WHERE OYA_TBL.CD1 = 1
OR
EXISTS (
SELECT Y.GOODS_NO
FROM OYA_TBL X INNER JOIN OYA_KO_TBL Y
ON (X.NO = Y.PACK_GOODS_NO)
WHERE (X.CD1 = 1) AND (Y.GOODS_NO = OYA_TBL.NO)
);

Oracleは使ってないので、Access2000で検証しました。
文法の違いなどがあれば読み替えて下さい。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。ちなみに、
親テーブルよりNOが2のレコードと(これは親子関係がないレコード)
親子関係のレコードの親レコードであるNOが1のレコードのみを取得したい場合(子レコードは不要)、どうすればよいでしょうか?
何度もすいませが、ご教授のほどよろしくお願い致します。

お礼日時:2007/12/24 19:59

一つのSQLではなく、一つのSELECTですか?


検証もしていない(できない)ので確実ではありませんが、一つのSELECTでは無理だと思います。
    • good
    • 0

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