外部結合がうまくいかない!PL/SQLでビューを作成している場合の対処法

このQ&Aのポイント
  • PL/SQLでビューを作成している際に、外部結合がうまくいかない問題が発生しています。
  • 具体的にはビュー「USERCOST.VW_KENSAKU_CUST」で外部結合の部分「CD2.CODENM1」の抽出ができない状況です。
  • 解決策として、外部結合の条件やテーブルの結合方法を確認し、正しい結合条件を設定する必要があります。
回答を見る
  • ベストアンサー

外部結合がうまくいきません。

PL/SQLでビューを作成しているのですが、外部結合がうまくいきません。 CREATE OR REPLACE VIEW USERCOST.VW_KENSAKU_CUST (CUSTID,TANTOU) AS SELECT Y.CUSTID, CD2.CODENM1 AS TANTOU, FROM T_YOYAKU Y, M_CODE CD2, (SELECT CUSTID,EDATE,JITUWORKERID            FROM T_YOYAKU            WHERE CUSTID || EDATE IN            (SELECT CUSTID || MAX(EDATE)            FROM T_YOYAKU            WHERE TO_DATE(EDATE,'YYYY/MM/DD') <= TO_DATE(SYSDATE,'YYYY/MM/DD') GROUP BY CUSTID )  WHERE  Y.CUSTID = AL.CUSTID AND Y.EDATE = AL.EDATE AND Y.JITUWORKERID = AL.JITUWORKERID AND CD2.CODEID(+) = '50' AND CD2.CODENO(+) = Y.JITUWORKERID / 抽出できないのは CD2.CODENM1です。どなたか知恵を貸して頂けませんでしょうか。お願い致します。                       

質問者が選んだベストアンサー

  • ベストアンサー
  • iwaz
  • ベストアンサー率57% (8/14)
回答No.1

どうもこんにちは。 まず、このSQL文ですがどこか抜け落ちているようで このままだと動作しないのでは? さて、CD2.CODENM1がうまく抽出できないとのことですが 具体的にどうなるのかがわからないのではっきりとは言え ませんが、以下の条件から CD2.CODEID(+) = '50' AND CD2.CODENO(+) = Y.JITUWORKERID Yテーブルから CD2テーブルへの外部結合でCODEIDが'50'の ものを抽出し、その場合にYテーブル側は全件抽出するという ように読み取れます。 この場合、CODEIDが'50'以外のレコードについてはCD2.CODENM1 がNULLとなってしまうと思います。CODEIDが'50'だけ抽出したい のであれば CD2.CODEID = '50' でいいかと思います。 あと結合の書き方も Y.JITUWORKERID = CD2.CODENO(+) と外部 結合される側を右辺に持っていった方がいいような気がします。 的外れな回答だったらすみません。(汗)

saruno
質問者

お礼

わざわざ長いソースを読んでくださりどうもありがとうございます。 外部結合はうまくいきました。 原因はテーブルの項目だったようです。 iwazさんの真心に感謝してポイント発行させていただきます。

関連するQ&A

  • Oracle8での外部結合

    現在、oracle8.1.7で開発しています。 T1,T2,T3の3つのテーブルがあります。 T1のデータで、T3のテーブルにまだデータが存在しないものを検索しています。 それは既にできました。 次に、条件として、  (1)T1のA,B,Cと一致し、かつFLGが5または9  (2)T1のA,B,Cと一致するデータがない。 という2点を追加しました。 しかし、以下のようにFLGが1となっているものまで検索してしまいます。   <T1>        <T2>      <T3> A:あいうえお     A:あいうえお    データ無し B:bbb        B:bbb C:ccc        C:ccc             FLG:1   ===SQL文============================================================== SELECT A,DT1,DT2 FROM T1 WHERE A LIKE 'あ%' ---追加部分---- AND ( EXISTS (SELECT A FROM T2 WHERE A=T1.A AND B=T1.B AND C=T1.C AND FLG IN (5,9)) OR NOT EXISTS (SELECT A FROM T2 WHERE A=T1.A AND B=T1.B AND C=T1.C ) ) ----ここまで---- AND NOT EXISTS (SELECT * FROM T3 WHERE KATAMEI='あ' AND NO=1) どこがいけないのでしょうか? よろしくお願いしますm(_ _)m

  • select文について

    SQLで情報を抽出しようとしています。 情報はFAX受信枚数です。 select distinct count(*)from <datebase A> where <page_no>='6' and to_char(receive_date,'yyyy/mm/dd') between 'YYYY/MM/DD' and 'YYYY/MM/DD'; 上記の構文だと、PAGE 6/6のついでに PAGE6/8なども一緒くたに情報を引っ張ってくると思われます。 今回知りたい情報はPAGE 6/6の受信枚数のみ なのですが、どうすれば条件に当てはまる式になるでしょうか。 なお、情報項目には、6/6を示す情報はありません。

  • SQL>UPDATEと同時にその件数をCOUNTする方法

    こんにちはtmgmです。 いまTANTOU_CDとTANTOU_NAMEという項目のある T_TANTOUというテーブルがあるとします。 TANTOU_CD_|_TANTOU_NAME_ _____1_|_担当者1___ _____2_|_担当者2___ _____3_|_担当者2___ 担当者2が二人いるのがわかりますか? ここでこの担当者2を”担当者3”に(どちらも)UPDATEしつつ、UPDATEした件数をCOUNTするSQL文の 書き方が分からずに困っています。 要するに UPDATE T_TANTOU SET TANTOU_NAME = '担当者3' WHERE TANTOU_CD = '担当者2' と SELECT COUNT(TANTOU_NAME) FROM T_TANTOU を同時にやりたいってことです。 どうすればよろしいでしょうか? ご返答よろしくお願いします。

  • 【SQL】複数行から最大値の取得

    以下のSQLを実行すると ENDDATE      PNO 2013/02/01 00000001 2013/02/01 00000002 2013/02/03 00000001 2013/02/01 00000003 2013/02/05 00000002 2013/02/01 00000001 2013/02/02 00000002 の様になります。 これを ENDDATE      PNO 2013/02/03 00000001 2013/02/01 00000003 2013/02/05 00000002 の様にENDDATEの最大値のみを残しPNOが重複しないものを抽出したいです。 以下のSQLをどの様に修正すれば可能でしょうか? ==SQL================================================== SELECT CO1.ENDDATE,AD1.PNO FROM COMMON CO1,ADMADMISSION AD1 WHERE CO1.DETAILOF IN ('10') AND AD1.CURRENTWARD=:CURRENTWARD AND CO1.STARTDATE BETWEEN TO_CHAR(TO_DATE(:CURRENTDATE)-:ENDLINE,'YYYY/MM/DD') AND TO_CHAR(TO_DATE(:CURRENTDATE)+:DEADLINE,'YYYY/MM/DD') UNION SELECT CO2.ENDDATE,CO2.PNO FROM COMMON CO2,ADMADMISSION AD2 WHERE CO2.DETAILOF IN ('10') AND AD2.CURRENTWARD=:CURRENTWARD AND CO2.ENDDATE BETWEEN TO_CHAR(TO_DATE(:CURRENTDATE)-:ENDLINE,'YYYY/MM/DD') AND TO_CHAR(TO_DATE(:CURRENTDATE)+:DEADLINE,'YYYY/MM/DD') UNION SELECT CO3.ENDDATE,CO3.PNO FROM COMMON CO3,ADMADMISSION AD3 WHERE CO3.DETAILOF IN ('10') AND AD3.CURRENTWARD=:CURRENTWARD AND :CURRENTDATE BETWEEN CO3.STARTDATE AND CO3.ENDDATE

  • 抽出が出来ないくらい遅いクエリ

    以下のようなクエリーを作成して検索を 行っているのですが、どうしても抽出が出来ないくらい 遅くどの部分で遅くしているのかが分からないため、 どなたか教えてもらえないでしょうか? ※足りない情報があればすみませんが、仰ってください。 なるべくプログラム(PHP等)を使わずクエリのみで 行いたいので、PHP云々の話しは無しでお願い致します。 最初の抽出テーブル(osi)と次の抽出テーブル(osday) をそれぞれ個別で動かすと普通の速度で抽出が旨く行きます が、それらをくっつけた形 select (省略) from osi,osday where osi.id=osday.id; とすると、抽出が行えない又は非常に遅いとなります。 ///////// 実際のクエリー文です ///////// select osday.odid,odctmid,saitemname,startday,endday from ( select odid,saitemname from order1 as o,sale as s where o.odid=s.saorderid and (o.odshipdue >= '2007-12-1 00:00:00' and o.odshipdue <= '2007-12-18 23:59:59') and (o.odcancelflag='0' or o.odcancelflag is null) and o.odclass<'4' and s.saregular='1' and s.saitemcode in (select itcode from item where itcategory='1') and odmakeday is not null ) osi , ( select odid,max(odctmid) as odctmid,to_char(min(o.odshipday), 'YYYY-MM-DD') as startday,to_char(max(o.odshipday), 'YYYY-MM-DD') as endday from order1 as o,sale as s where o.odid=s.saorderid and (o.odshipdue >= '2007-12-1 00:00:00' and o.odshipdue <= '2007-12-18 23:59:59') and (o.odcancelflag='0' or o.odcancelflag is null) and o.odclass<'4' and s.saregular='1' and s.saitemcode in (select itcode from item where itcategory='1') and odmakeday is not null group by o.odid ) osday where osi.odid=osday.odid; ///////////////////////////////////////////

  • DATE型カラムのインデックスが効かない

    Oracle初心者です。 以下のような2種類のSQLをSQLPLUSで実行し、 実行計画を取得しました。 end_timeでfilterをかける際に、"TABLE ACCESS FULL"となっており、貼っているインデックスが使われていないことがわかりました。 #これがSQLの遅い主要因と考えています。。。。勘です。 インデックスが活用されていない原因としてはどのようなものが考えられるのでしょうか。 宜しくお願いいたします。 1) set autotrace traceonly select * from t_sample where end_time >= '2009-08-25' and end_time <= '2009-11-26' 2) set autotrace traceonly select * from t_sample where end_time >= to_date('2009-08-25', 'yyyy-mm-dd') and end_time <= to_date('2009-11-26', 'yyyy-mm-dd')

  • 外部結合のSQLの書き方について

    SQLの書き方について質問です。 マスタにある項目CDはすべて表示。そこにデータ項目を表示させる。マスタにある項目CDがデータにない場合は、表示できない部分以外はNULLで表示させるにはどうしたらよいのでしょうか? 思うようにデータが取得できません。ORACLE8iです。 例えば select * from マスタ where データCD = '0009' の結果が +-------------------------------------+ + データCD | SEQ番号 | 項目CD | 項目名 | +-------------------------------------+ 0009 | 1 | 05000 | 名称1 0009 | 2 | 05100 | 名称2 0009 | 3 | 05200 | 名称3 で、 select * from データ and データ.本支所CD = '999' and データ.部門CD = '99' の結果が +------------------------------------------+ + 本支所CD | 部門CD | 項目CD | 発生額07月 | +------------------------------------------+ 999 | 99 | 05000 | 1,234 999 | 99 | 05100 | 1,235 だった場合、 select SEQ番号, 本支所CD, マスタ.項目CD, マスタ.項目名, 発生額07月 from マスタ,データ where マスタ.データCD = '0009' and マスタ.項目CD = データ.項目CD and データ.本支所CD = '999' and データ.部門CD = '99' を実行すると、 +--------------------------------------------------------+ | SEQ番号 | 本支所CD | 部門CD | 項目CD | 項目名 | 発生額07月 | +--------------------------------------------------------+ | 1 | 999 | 99 |05000 | 名称1 | 1,234 | 2 | 999 | 99 |05100 | 名称2 | 1,235 +--------------------------------------+ と結果が返ってきますが、 +-------------------------------------------------------+ | SEQ番号 | 本支所CD | 部門CD | 項目CD | 項目名 | 発生額07月 | +-------------------------------------------------------+ | 1 | 999 | 99 |05000 | 名称1 | 1,234 | 2 | 999 | 99 |05100 | 名称2 | 1,235 | 3 | 999 | 99 |05200 | 名称3 | NULL +--------------------------------------+ とするためには どういうSQLを作成したらよいのでしょうか? 「where マスタ.データCD(+) = '0009' and マスタ.項目CD = データ.項目CD(+) and データ.本支所CD(+) = '999' and データ.部門CD(+) = '99' 」 にしてもだめでした。 ※「マスタに存在して、データに存在しない項目コードがありますが、 それも発生額07月はNULLでよいので、それ以外の項目をすべて表示したい」のです。 説明不足だとは思いますが、どなたかご教授のほどよろしくお願いいたします。相当行き詰ってます。

  • SQLの質問です。

    Oracle Database Express Editionを使って勉強中の者です。 商品TBL、予約TBL、明細TBLと3つのテーブルを使用して、商品に対して予約と受取の明細がきちんと出ているのか、件数を出すSQLを組みたいと思っています。 例えば、 【商品TBL:shohin】 shohin_no / shohin_nm / price ----------------------------- s001 / name1 / 1000 s002 / name2 / 1500 s003 / name3 / 2000 【予約TBL:yoyaku】 yoyaku_no / shohin_no / status(1:予約, 2:受取) ----------------------------- y001 / s001 / 1 y001 / s001 / 2 y002 / s001 / 1 y002 / s002 / 1 y002 / s002 / 2 【明細TBL:receipt】 shohin_no / status / receipt ----------------------------- s001 / 1 / abc.. s001 / 2 / def.. s002 / 1 / ghi.. 【想定結果】 商品NO / 予約数 / 予約明細数 / 受取数 / 受取明細数 ----------------------------- s001 / 2 / 1 / 1 / 1 s002 / 1 / 1 / 1 / 0 s003 / 0 / 0 / 0 / 0 としたいのですが、どうにも上手くいかず、下記のような結果が返ってきます。 【結果】 商品NO / 予約数 / 予約明細数 / 受取数 / 受取明細数 ----------------------------- s001 / 2 / 2 / 2 / 2 s002 / 1 / 1 / 1 / 0 s003 / 0 / 0 / 0 / 0 私が実行したSQLは下記です。 恐らく何か初歩的な所で間違っているような気がするのですが、自分では分からず…。 一体何がいけないのか、ご教授の程、よろしくお願い致します。 select shohin.shohin_no as "商品NO" ,count(yoyaku_1.shohin_no) as "予約数" ,count(receipt_1.shohin_no) as "予約明細数" ,count(yoyaku_2.shohin_no) as "受取数" ,count(receipt_2.shohin_no) as "受取明細数" from shohin ,(select * from yoyaku where yoyaku.status = '1') yoyaku_1 ,(select * from yoyaku where yoyaku.status = '2') yoyaku_2 ,receipt receipt_1 ,receipt receipt_2 where yoyaku_1.shohin_no(+) = shohin.shohin_no and yoyaku_2.shohin_no(+) = shohin.shohin_no and receipt_1.shohin_no(+) = yoyaku_1.shohin_no and receipt_1.status(+) = yoyaku_1.status and receipt_2.shohin_no(+) = yoyaku_2.shohin_no and receipt_2.status(+) = yoyaku_2.status group by shohin.shohin_no order by 1

  • SQLServerのPIVOT絡みの処理

    お世話になります。 従来はVB6のプログラム中で、従来ACCESSMDBからデータを取得していました。 これをDBを変更し、データ自体はOracle、接続先はSQLServer(2005)との仕組みに変更することとなりました。 (SQLServerのリンクサーバ機能にてOracleからデータを取得する) ここで、元のアクセスにて行っていたクロス集計を移行するため 次のようなSQL文(メイン部位以外は端折ってます)を書いたのですが、 「オペランドのデータ型 nvarchar は sum 演算子では無効です」 との警告が出てしまいます。 (”SUM(oraData.suuryou)” を、”Count(oraData.suuryou)”とした場合はデータ取得できました。) 原因、及び回避策についてお知恵を拝借できませんでしょうか? (PIVOT相当の処理をプログラム側で行うことで回避できますが、できればSQLで終えてしまいたいです) SELECT     pvt.moji    ,pvt.moji2    ,SUM([01]), SUM([02]), SUM([03]), SUM([04]), SUM([05]), SUM([06]), SUM([07]), SUM([08]), SUM([09]), SUM([10])     ,SUM([11]), SUM([12]), SUM([13]), SUM([14]), SUM([15]), SUM([16]), SUM([17]), SUM([18]), SUM([19]), SUM([20])     ,SUM([21]), SUM([22]), SUM([23]), SUM([24]), SUM([25]), SUM([26]), SUM([27]), SUM([28]), SUM([29]), SUM([30])     ,SUM([31])  From    openquery  (LinkServerName, '      SELECT        moji       ,moji2       ,hiduke       ,TO_CHAR(hiduke, ''dd'') AS dd       ,hiduke       ,suuryou       ,Sum(suuryou) AS suuryou      FROM        table      WHERE        hiduke BETWEEN TO_DATE(''2008/04/01'', ''YYYY/MM/DD'') AND TO_DATE(''2008/04/30'', ''YYYY/MM/DD'')       UNION      SELECT        moji       ,moji2       ,hiduke       ,TO_CHAR(hiduke, ''dd'') AS dd       ,hiduke       ,suuryou       ,Sum(suuryou) AS suuryou      FROM        table      WHERE        hiduke BETWEEN TO_DATE(''2008/04/01'', ''YYYY/MM/DD'') AND TO_DATE(''2008/04/30'', ''YYYY/MM/DD'')     ') AS oraData PIVOT     (         SUM(oraData.suuryou)         FOR oraData.dd IN           (              [01], [02], [03], [04], [05], [06], [07], [08], [09], [10]              ,[11], [12], [13], [14], [15], [16], [17], [18], [19], [20]              ,[21], [22], [23], [24], [25], [26], [27], [28], [29], [30]              ,[31]            )      ) AS pvt WHERE    moji = "xxx" OR moji2 = "yyy"

  • GROUP BY使用時のソートについて

    OracleSqlにて「GROUP BY」使用した日付のデータを取得するSql文を作成したのですが、 「ORDER by」句に「DESC」を付けても降順ソートが行えません。 作成したSql文は以下の通りなのですがなぜ降順ソートが行えないのでしょうか? 「GROUP BY」を使用するとソート出来ないと言うことなのでしょうか? それとも日付型なのでソートが出来ないと言うことなのでしょうか? どなたかご存知の方おりましたらご教授下さい。 ------------------------------------------------- SELECT TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY FROM STOCKTBL WHERE TO_CHAR(RECORDDATE,'YYYY/MM/DD')<='2002/03/07' AND TO_CHAR(RECORDDATE,'YYYY/MM/DD')>='2002/02/22' GROUP BY TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY ORDER by TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY DESC -------------------------------------------------