- ベストアンサー
SQLのUPDATE文でテーブルの日付を更新する方法
- SQLのUPDATE文を使用してテーブルの日付を更新する方法について教えてください。
- テーブル1の日付が空白のレコードを対象に、テーブル1とテーブル2の特定の項目が一致する場合、テーブル1の日付をテーブル2の日付で更新したいと考えています。
- しかし、提供されたUPDATE文でエラーが発生しています。set文の記述方法が間違っているようです。正しい記述方法を教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
>>また主キーにすることで記述を変えることが出来る 主キーである必要はありません。 簡単に書きすぎたので、少し説明しますと…… No.1の2番目のUPDATE文の場合、 更新される方(この場合テーブル1)の行に対して 更新する方(この場合テーブル2)に該当する行が複数存在すると、 どのデータで更新すればよいのかOracleにはわからないわけです。 テーブル2が一意になることを保障してやる必要があります。 保障する方法の1つが主キーを貼ることなのですが、 テーブル2のキー項目(品番+規格+取引先)で 一意索引を作成してもかまいません。 # うまく説明できてないな…… # 「更新可能なビュー」「ORA-01779」あたりで検索してください。 >>in条件が使えない理由 特定のデータでうまくいかないのであれば、そのデータを…… Oracleがエラーメッセージを返すのであれば、そのメッセージを…… うまくいかない状況を挙げてみてはいかがでしょう。 # 両テーブルの主キーは何だろう?
その他の回答 (5)
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
>”いろいろ問題”に関して少しだけ具体的な事例があれば教えて下さい。 key1,key2,key3 AAA,AAA,AAA AA,AA,AAAA AA,AAA,AAAA A,A,AAAAAAA key||key2||key3やconcat(concat(key1,key2),key3)は、Aの並び9個になります。 異なるレコードにも関わらず、区別がつきません。 (key1,key2,key3) in (select key1,key2,key3 from hoge) は、当然区別します。 なぜ、in条件が使えないのか、未だに理解できていませんが、in条件が使えない、 または効率的に使わないほうが良い場合には、existsを使うのが良いでしょう。 同様に、not in条件が非効率な実行計画となる場合も、not existsを試行してみると良いかと思います。 オプティマイザが賢ければ、同じ計画となるべきところでも、実際は異なるケースも多々あるので、 都合の良い方を選択的に採用すると良いと思いますよ。
- dda167
- ベストアンサー率76% (55/72)
>>複数項のIN条件がエラー まさか…… キー(と思われる)項目にNULLが入っていたりしないでしょうねえ(^^;
補足
dda167様、 ご回答ありがとうございます。 NULL確認しましたが、存在しませんでした。 全てのレコードのキー項目にデータが入っています。
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
#2ですが・・ SQL書いているうちに、#1と思い切りかぶりました。忘れてください。
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
前回の質問で、締め切り済みでコメントできなかったのですが・・ CONCATで単一文字列にして、IN条件とするのは、いろいろ問題があります。 なぜ、複数項のIN条件がエラーになったのか気になりますが、どうしても使えないなら、 existsでの書き換えが可能です。 例えば、今回のSQLの場合だと、次のような条件式への書き換えになります。 (更新項目の右辺は、今回の質問に対する回答に相当します) update テーブル1 set テーブル1.日付 = ( select テーブル2.受入日 from テーブル2 where テーブル1.品番=テーブル2.品番 and テーブル1.規格=テーブル2.規格 and テーブル1.取引先=テーブル2.取引先 ) where テーブル1.日付 Is Null and exists( select 1 from テーブル2 where テーブル1.品番=テーブル2.品番 and テーブル1.規格=テーブル2.規格 and テーブル1.取引先=テーブル2.取引先 );
補足
k_o_r_o_c_h_a_n様、 前回に引き続きご支援ありがとうございます。 前回自分なりに出来たと思っていたのですが、まだまだでした。 ご回答頂いた中に >CONCATで単一文字列にして、IN条件とするのは、いろいろ問題があります。 とありますが、”いろいろ問題”に関して少しだけ具体的な事例があれば教えて下さい。 何か懸念点があればconcat方法を止めないといけないと思いました。 宜しくお願い致します。
- dda167
- ベストアンサー率76% (55/72)
テーブル2の受入日がNULLの場合は除外しています。 update テーブル1 set 日付 = ( select 受入日 from テーブル2 where テーブル2.品番 = テーブル1.品番 and テーブル2.規格 = テーブル1.規格 and テーブル2.取引先 = テーブル1.取引先 ) where テーブル1.日付 is null and exists ( select * from テーブル2 where テーブル2.品番 = テーブル1.品番 and テーブル2.規格 = テーブル1.規格 and テーブル2.取引先 = テーブル1.取引先 and テーブル2.受入日 is not null ); たとえば、品番+規格+取引先が主キーの場合、 以下のように書くこともできます。 update ( select t1.日付, t2.受入日 from テーブル1 t1, テーブル2 t2 where t1.品番 = t2.品番 and t1.規格 = t2.規格 and t1.取引先 = t2.取引先 and t1.日付 is null and t2.受入日 is not null ) set 日付 = 受入日;
補足
dda167様、 ご回答ありがとうございます。 ”exists”を使ってサンプル頂いた内容で更新できることを確認しました。 また主キーにすることで記述を変えることが出来ることも分かりました。 まだまだ初心者で日々勉強の毎日ですので、また何かありましたらご支援をお願い致します。
お礼
k_o_r_o_c_h_a_n様、 非常に分かりやすいご説明ありがとうございます。 同じ並びになってしまう可能性があるということが非常によく分かり理解できました。 in条件が使えない理由は色々試してみます。 まだまだ最初の一歩を踏み出したところですのでこれからもご教授お願い致します。