• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ORACLE INSERT文を教えて下さい)

ORACLE INSERT文の実現方法とは?

このQ&Aのポイント
  • ORACLEのINSERT文で、指定の条件に基づいてTBL_AからTBL_Bへデータを出力する方法を教えてください。
  • TBL_Aから1レコードずつ読み込み、グループ情報のあるVIEWから最新のview_GRPCDを取得し、TBL_Bへ出力します。
  • しかし、VIEW上に存在しないTBL_AのレコードもTBL_Bに出力したいため、この要件を満たすINSERT文を作成したいと思っています。

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

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

検証できる環境が今ないのですが、カーソルを使わず外部結合を使えばいいのではないでしょうか。 SELECT A.ENCD, NVL(View_GRPCD,0), A.SYOCD, A.URI FROM (SELECT TENCD,SYOCD,SUM(URIAGE) URI FROM TBL_A GROUP BY TENCD,SYOCD ORDER BY TENCD,SYOCD) A left join ( select View_TENCD,View_WRICD,View_GRPCD from (SELECT View_TENCD,View_WRICD,View_GRPCD, RANK() OVER(PARTITION BY View_TENCD ORDER BY View_YMD DESC, View_GRPCD DESC) w_RANK FROM View ) where w_RANK = 1 ) on View_TENCD = w_TENCD

tkuzume
質問者

お礼

nora1962 様 ご回答、ありがとうございます。 そうですね、カーソル必要ないかも(仕様の段階で「カーソルでまわせばいい」と 言われたので、その方法しか無いと思っていました) 頂いたSQLをじっくり適用してみようと思います。 (まだ皆様のようにすぐには理解出来ないので・・・) いつもありがとうございます。 またよろしくお願いします

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

  • yamada_g
  • ベストアンサー率68% (258/374)
回答No.3

>VIEW上にないレコードは作成されませんでした。 とありますが、 >FROM View >WHERE View_TENCD = w_TENCD としているので存在しないTENCDのデータは取得できないので当然ですね。 他の回答者様も言っているように、外部結合すれば問題ないと思います。 --全角でインデントしてます。 INSERT INTO TBL_B SELECT  A.TENCD,NVL(B.GRPCD,'000'),A.SYOCD,A.URIAGE FROM  TBL_A A  LEFT JOIN (   SELECT GRPCD,TENCD   FROM (    SELECT     GRPCD,TENCD     ,ROW_NUMBER() OVER(PARTITION BY TENCD ORDER BY YMD DESC,GRPCD DESC) RNUM    FROM   V)   WHERE RNUM = 1 ) B  ON A.TENCD = B.TENCD; No.2様の考え方と同様ですが、No.2様のそのままのSQLだと内側のサブクエリが期待どおりにならないと思います。 where rownum = 1 の条件はorder by より先に適用されるので 降順で並べた1件目、にはならないはずです。(たまたまなる時もあるかもしれませんが) select * from (select * from tbl order by ソート条件) where rownum = 1 という風に一旦ソートしたサブクエリを作る必要があります。

tkuzume
質問者

お礼

yamada_g 様 ご回答ありがとうございます。 >where rownum = 1 の条件はorder by より先に適用されるので この辺りの適用される順番についてあまり理解していなかったので、 今までのロジックも見直してみました。 ご提示頂いたSQLも参考にさせて頂きたいと思います。 いつもありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.2

1レコードずつ処理しているようですが、1発でできますよ。 先ず、理論の展開を考えると、以下のようになります。 (1)Viewを日付、グループコードの降順でソートしたものの  先頭1レコードを返すサブクエリ (2)TBL_Aと上記サブクエリをOUTER JOINしたクエリを  元にしてTBL_Bに挿入 これを元にSQLを組み立てます. INSERT INTO TBL_B SELECT A.TENCD, DECODE(B.GRPCD,NULL,'000',B.GRPCD) GRPCD, A.SYOCD,A.URIAGE FROM TBL_A A LEFT JOIN (SELECT View_GRPCD GRPCD FROM View WHERE ROWNUM=1 ORDER BY View_YMD DESC, View_GRPCD DESC) B ON A.GRPCD=B.GRPCD こんな感じですが如何でしょう。

tkuzume
質問者

お礼

nda23 様 ご回答、ありがとうございます。 やはり、カーソルにする必要は無いようですね。 頂いたSQLを今回の仕様にじっくり適用してみようと思います。 (まだ皆様のようにすぐには理解出来ないので・・・) 大変ありがとうございました。 またよろしくお願いします

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • ORACLE のSQL について

    おはようございます。 ORACLEのSQLについて教えてください。 GROUP BY で抽出されたデータの レコード数を把握するSQLはどのようにすればよいのでようか。 ********************** 例: SQL: SELECT TEST_CD FROM TABLE GROUP BY TEST_CD 結果: 01 02 03 04 05 ********************** この結果のレコード(5レコード)のSQL式はどのようになりますか?

  • SELECT文について

    対象のテーブルを以下とした時に、 GROUP「001」と「002」のそれぞれの「値1」「値2」の合計値を表示したいのです。 テーブル名 TBL_1 |グループ1| 値1 | 値2 | |  A   |  2  |  4  | |  A   |  3  |  7  | |  B   | 10  |  5  | |  B   | 15  |  8  | |  C   | 20  | 30  | |  C   | 15  | 25  | 取得したい結果は以下です。 | グループ_A合計値1 | グループ_A合計値2 | グループ_B合計値1 | グループ_B合計値2 | |      5        |      11        |      25        |      13       |   色々と試したのですが、ハマってしまいました。 SQLを教えて頂けないでしょうか。お願いします。

  • ORACLEでの件数カウント方法

    素人なので教えてください。sqlplusでレコード件数をカウントしたいのですが、チョット特殊なカウント方法なのです。やりたいことは、一回のSQL文で複数カラムのレコード件数をカウントしたいのですが可能でしょうか? 例) a_cdの件数カウントの場合は、 select a_cd,count(*) from abc group by a_cd; で b_cdの件数カウントの場合は、 select b_cd,count(*) from abc group by b_cd; これを一回のSQLで、 a_cdとb_cdの件数をカウント出来ますか?

  • plpgsqlのエスケープ文字について

    plpgsqlのエスケープ文字について教えてください tblのテーブルのnameフィールドの値をtitleフィールドに更新する関数を作成してます。 cur cursor for SELECT id, name FROM tbl; rec RECO RD; begin open cur; LOOP FETCH cur INTO rec; EXIT WHEM NOT FOUND; w_sql := ''UPDAT tbl SET title = ''; w_sql := w_sql ll '' ''''タイトル: '' ll rec.name ll '' '''' ''; w_sql := w_sql ll '' WHERE id= '' ll rec.id= '' ll rec.id ; EXECUTE w_sql; END LOOP; ・ ・ ・ ・ ・ 上記のようにnameフィールドの値をset句に設定していますが、 nameフィールドには 「90's」 や「men's」 のような値が入ったレコードがあるためエラーとなってしまいます。 name内の「'」をエスケープする為にはどのように書けばよいでしょうか 教えてください

  • MySQLで対象期間を決め集計しランキングする方法

    MySQLの初心者ですが、対象期間で集計を行いランキング付けし任意の上位何位までを抽出する方法について教えてください。 全データから集計後上位5位を選ぶ場合・・同順有り select x.`品名`,x.kei,(select count(*)+1 from (select `品名`,sum(`金額`) as kei from uriage group by `品名`) y where x.kei<y.kei ) as rank from (select `品名`,sum(`金額`) as kei from uriage group by `品名`) x having rank <= 5 order by rank といろいろ参考にしてで出来ましたが。任意の対象期間(日付)を設定して実行するSQL文が思いつきません。どこに期間を挿入するのか・・・悪あがきで思い付いた方法として CREATE OR REPLACE VIEW uriage_01 AS SELECT `品名`,SUM(`金額`) AS `金額` FROM uriage WHERE `日付` BETWEEN "2001/01/01" AND "2001/01/31" GROUP BY `品名` で任意期間の集計結果のビューを作りそのビューから select r1.`品名` as `品名`, r1.`金額` as p, count(r2.`金額`)+1 as rank from uriage_01 as r1 left join uriage_01 as r2 on r1.`金額` < r2.`金額` group by r1.`品名` having rank <= 5 order by rank と手間の掛かる方法です。単純に5行だけに限定ならorder by `金額`Limit 5 にすれば良いだけですけど・・・同順があるとどうすれば良いのかと思考停止状態です。尚、当方は、MySQLの勉強を始めたばかりにですので宜しくお願いいたします

    • ベストアンサー
    • MySQL
  • Oracle 10.2.0 でMAX集計がおかしい!?

    VB6 で oo4o を使って Oracle DB開発をしています。 Oralce 8.1.6 から Oracle10.2.0 にサーバを切り替えました。 bというテーブルがあって、 a c d ---- ------ ----- 10 2 1 20 3 1 30 4 1 40 5 1 50 6 2 というデータがあったとします。 Select MAX(a) as a from b WHERE d=1 のようなSQLをVBから発行したときに SQL*PLUSでは、 a ---- 40 という結果が返ってくるのですが、VBでは、 a --- 10 20 30 40 のように複数行のレコードセットが帰ってきます。そのため、最大行を取得できません。Oracle8 のときは、SQL*PLUSと同じ結果が返ってきていました。ちなみに Select MAX(a) as a from b WHERE d=1 GROUP BY d ~~~~~~~~~~ と、GROUP BYを付けると、ただしい(SQL_PLUSと同じ値)値が取得できます。 Oracle10.2.0の問題か、oo4oの問題かと考えています。 ちなみにoo4oのオブジェクトは、 CreateObject("OracleInProcServer.XOraSession") で作成していて、クライアントのバージョンは 9.2.0.4.4です。 長文で失礼しますが、どなたかSQLを変更せずに解決する方法をご存じないでしょうか?

  • GROUP BYについて

    初歩的な質問になってしまいますが、GROUP BYの使い方について解らない点があるので、宜しくお願いします。 次のようなボーリング大会のレコードがあったとして、 ========bowling TBL (以下、フィールド名)===================== 氏 名|ゲーム回数|1投目|2投目|3投目|・・10投目| ============================================================ 注※ゲーム回数はintで1からインクリメントしていく。 氏名別に1番最後に行ったゲームを参照したい場合 ●SELECT 氏名 MAX(ゲーム回数) GROUP BY 氏名 で、 ----------------------------------------------------- Aさん|3| Bさん|5| ----------------------------------------------------- が得られますが、更にこの最終ゲームでの1投目と2投目の結果のみを付け足し、 ----------------------------------------------------- Aさん|3|12本|19本| Bさん|5|03本|15本| ----------------------------------------------------- のように参照したい場合、どのようなSQL文になるのでしょうか? どなたかご教示宜しくお願いします。

    • ベストアンサー
    • MySQL
  • UPDATE文の書き方を教えて下さい。

    いつもお世話になっています。 UPDATEの書き方について教えて下さい。 以下のようなUPDATE文を作成しました。 処理的には必要な結果を返してくれていますが、もう少しシンプルには ならないでしょうか? UPDATE文がまだ理解出来ていないのですが、”WHERE EXISTS(”以降に 書いているSELECT文は、SET文の値算出時にも同じSELECT文を書いて いるのですが、それを代用することは出来ないのでしょうか? (SELECTの結果をWHERE文の中で簡単に呼び出して使えないのでしょうか?) ※うまく内容が伝わってないかもしれませんが、どうぞよろしくお願いします。 <<<更新処理>>> UPDATE TBL01 SET( TBL01_MARNO, TBL01_UPDYMD )=( SELECT TBL02_MARNO, TO_NUMBER(TO_CHAR(SYSDATE,'YYYYMMDD')) FROM (SELECT TBL02_TENCD, TBL02_REN, TBL02_MARNO, TBL02_UPDKBN, RANK () OVER (PARTITION BY TBL02_TENCD, TBL02_REN ORDER BY TBL02_YMD DESC, TBL02_DAT DESC ) WRK_RANK FROM TBL02 WHERE TBL02_OKFLG = 1 ) WHERE TBL02_TENCD = TBL01_TENCD AND TBL02_REN = TBL01_REN AND WRK_RANK = 1 AND TBL02_UPDKBN = 2 ) WHERE EXISTS( SELECT 'TRUE' FROM (SELECT TBL02_TENCD, TBL02_REN, TBL02_MARNO, TBL02_UPDKBN, RANK () OVER (PARTITION BY TBL02_TENCD, TBL02_REN ORDER BY TBL02_YMD DESC, TBL02_DAT DESC ) WRK_RANK FROM TBL02 WHERE TBL02_OKFLG = 1 ) WHERE TBL02_TENCD = TBL01_TENCD AND TBL02_REN = TBL01_REN AND TBL02_UPDKBN = 2 AND WRK_RANK = 1 );

  • ACCESSでINSERT文を行うとき

    ACCESSで[入力テーブル]から[実績テーブル]へINSERT文を行うと、[実績テーブル]に追加されたレコード順番が、[入力テーブル]に書き込まれたレコードの順番と合わなくなってしまいます。 例 [入力テーブル]   [実績テーブル] --------------------------------------------- A         → A B         → C C         → D D         → B とくにORDER BY句を使っているわけではないのですが、原因として何が考えられるのでしょうか? どちらのテーブルにもIDを持ってそのIDでソートすれば良いのかもしれないのですが、ワケあって入力テーブルにIDを持たせるのが難しいのです。 アドバイスお願いいたします。

  • SQL文について

    TBL_A カラム1 |カラム2 |カラム3 |カラム4 | ---------|---------|---------|---------| 1    |AAA   |N    |1    | ---------|---------|---------|---------| 2    |AAA   |G    |1    | ---------|---------|---------|---------| 3    |BBB   |N    |0    | ---------|---------|---------|---------| 4    |CCC   |N    |0    | ---------|---------|---------|---------| TBL_B カラム1 |カラム2 | ---------|---------| AAA   |2    | ---------|---------| BBB   |0    | ---------|---------| CCC   |1    | ---------|---------| 上記のテーブル、TBL_A、TBL_Bがあるとします。 TBL_Aからカラム3='N'を抽出し、TBL_Bのカラム2でソートしたいのですが、 可能でしょうか? 結果 ---------|---------| BBB   |0    | ---------|---------| CCC   |1    | ---------|---------| AAA   |2    | ---------|---------| …となって欲しいのですが。。。 select TBL_A.カラム2 from TBL_A, TBL_B where TBL_A.カラム3='N' order by TBL_B.カラム2 では、うまくいきませんでした。 ※ TBL_A、TBL_Bは共にカラム1がキー値です。