質問 |
||
| QNo.3623218 | SQL文でご質問です | |
|---|---|---|
| 質問者:oyaji111 |
ご存知の方がおられましたら、教えて下さい。 下記のように、親テーブルと親子を管理するための親子管理テーブルがあります。 条件として、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 |
|
困り度:
|
||
| 質問投稿日時: 07/12/24 10:15 |
||
回答良回答20pt |
|
| ANo.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でも動きそうなものを選んで下さい。 |
|---|---|
| 回答者:venzou | |
| 種類:回答 どんな人:経験者 自信:参考意見 |
|
| 回答日時: 07/12/25 00:09 |
|
| |
| この回答へのお礼 | 色々とご教授下さり、ありがとうございました。 CD1の条件が必要ない場合もあるようで、その場合は親子関係のレコードを全て抽出する必要があり、そうすると最初に教えていただいたexistを使ったSQLだと、親レコードしか取得できなかったので、 LEFT JOIN の結合をメインにしたSQL文を採用させていただきました。 僕自身、あまりexist条件って使った事がなかったので、勉強になりました。本当に、助かりました。ありがとうございました。 |
回答 |
|
| ANo.2 | 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で検証しました。 文法の違いなどがあれば読み替えて下さい。 |
|---|---|
| 回答者:venzou | |
| 種類:回答 どんな人:一般人 自信:参考意見 |
|
| 回答日時: 07/12/24 12:04 |
|
| |
| この回答へのお礼 | ご回答ありがとうございます。ちなみに、 親テーブルよりNOが2のレコードと(これは親子関係がないレコード) 親子関係のレコードの親レコードであるNOが1のレコードのみを取得したい場合(子レコードは不要)、どうすればよいでしょうか? 何度もすいませが、ご教授のほどよろしくお願い致します。 |
回答 |
|
| ANo.1 | 一つのSQLではなく、一つのSELECTですか? 検証もしていない(できない)ので確実ではありませんが、一つのSELECTでは無理だと思います。 |
|---|---|
| 回答者:assault852 | |
| 種類:アドバイス どんな人:一般人 自信:参考意見 |
|
| 回答日時: 07/12/24 11:16 |
|
| |
| この回答へのお礼 | この回答にお礼をつける(質問者のみ) |