- 締切済み
UPDATE文を教えてください
管理テーブルというテーブルがあります。 フィールド構成は、会社コード(6)/支店コード(2) SEQNO(2)/管理年月(6)/管理番号(8)となっていて、SeqNOがKeyとなっています。 会社コード|支店コード SeqNO 管理年月 管理番号 (1) 000001| 01 | 01 | 200503 |00000000 (2) 000001| 01 | 02 | 200503 |00000000 (3) 000001| 02 | 03 | 200503 |00000000 (4) 000001| 02 | 04 | 200503 |00000000 (5) 000001| 01 | 05 | 200502 |11111111 (6) 000001| 01 | 06 | 200502 |11111111 (7) 000001| 02 | 07 | 200502 |22222222 (8) 000001| 02 | 08 | 200502 |22222222 こんな感じでデータがあります。 会社コード/支店コード/管理年月が同じものの管理番号は、必ず同じデータが入ります。 これは、実際のデータはさらに複雑ですが、簡単にするため変なデータに思えると思います。まあそこは気にしないでください。 実は、(1)~(4)の管理番号がミスでデータが落ちてしまいました。 管理テーブルの管理年月が200502の会社コードと支店コードが同じ管理番号を同じデータの200503の管理番号に更新するSQLを教えてください。 一応作ってみましたが、 ”単一行副問合せにより2つ以上の行が返されます。”が出てしまって・・ 分からないので教えてください。 UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT T2.管理番号 FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502) WHERE (T1.会社コード,T1.支店コード) IN (SELECT T3.会社コード,T3.支店コード FROM 管理テーブル T3 WHERE T3.管理年月 = 200503 GROUP BY T3.会社コード,T3.支店コード)
- みんなの回答 (6)
- 専門家の回答
みんなの回答
- iiikkk
- ベストアンサー率37% (92/247)
UPDATE 管理テーブル T1 SET T1.管理番号 = nvl(( SELECT DISTINCT T2.管理番号 FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 ), 00000000) WHERE T1.管理年月 = 200503 これではどうでしょうか?
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
#3ですが.. よくよく見ると・・、更新対象レコードの限定の仕方がうまくない。 UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT T2.管理番号 FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 and ROWNUM=1 ) WHERE (T1.会社コード,T1.支店コード) IN (SELECT T3.会社コード,T3.支店コード FROM 管理テーブル T3 WHERE T3.管理年月 = 200503 GROUP BY T3.会社コード,T3.支店コード) and T1.管理年月 = 200503 /* <========ここ== */ ただ、更新件数も多くなるはずだし、管理年月=200502のレコードの管理番号が"00000000"になることは無いと思います。 管理年月=200503以外のレコードまで、管理年月=200502の管理番号で更新されるハズです。 なので、事態が理解できないカンジです。
お礼
ありがとうございました。 このSQLでうまく行きました。結構こういう変なファイル が多いので今後活用させて頂きます。 とても勉強になりました。
- taka_tetsu
- ベストアンサー率65% (1020/1553)
#1です。 UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT MAX(T2.管理番号) FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 GROUP BY T2.会社コード, T2.支店コード) WHERE T1.管理年月 = 200503 すみません。管理番号を抽出する方のselectに集計関数付け忘れました。
お礼
ありがとうございました。エラーもなく更新件数がぴったり合ったので出来た!と喜びましたが、 結果を見ると管理番号が全て0000000に置き換わってしまいました。これはやばい!です。
- k_o_r_o_c_h_a_n
- ベストアンサー率55% (526/942)
レコード(1)~(4)を更新するとき、相関性のあるデータの検索条件が甘いので、 レコード(1)に対し、(5)(6)が該当する。 レコード(2)に対し、(5)(6)が該当する。 レコード(3)に対し、(7)(8)が該当する。 レコード(4)に対し、(7)(8)が該当する。 という感じで、複数該当するので、オラクルはどちらを採用して良いか不明なため エラーとしています。 今回のケースではどちらでも良いということなので、どちらでも良いから1件だけ限定する 条件を書き加えればOKです。 UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT T2.管理番号 FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 and ROWNUM=1 /* <===========1件だけよ==== */ ) WHERE (T1.会社コード,T1.支店コード) IN (SELECT T3.会社コード,T3.支店コード FROM 管理テーブル T3 WHERE T3.管理年月 = 200503 GROUP BY T3.会社コード,T3.支店コード)
お礼
ありがとうございました。エラーもなく更新件数がぴったり合ったので出来た!と喜びましたが、 結果を見ると管理番号が全て0000000に置き換わってしまいました。これはやばい!です。
- raphel_7
- ベストアンサー率34% (86/252)
間違ってるかもしれませんが・・・。 UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT T2.管理番号 FROM (SELECT T3.会社コード,T3.支店コード FROM 管理テーブル T3 WHERE T3.管理年月 = 200503 GROUP BY T3.会社コード,T3.支店コード ) T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 ) こんな感じでどうでしょう。
お礼
ありがとうございました。参考にさせて頂きました。 でも T2.管理年月 = 200502でエラーが出てしまいました。思うに管理年月が選択されていないからでは・・
- taka_tetsu
- ベストアンサー率65% (1020/1553)
これでどうかな? UPDATE 管理テーブル T1 SET T1.管理番号 = (SELECT T2.管理番号 FROM 管理テーブル T2 WHERE T2.会社コード = T1.会社コード AND T2.支店コード = T1.支店コード AND T2.管理年月 = 200502 GROUP BY T2.会社コード, T2.支店コード) WHERE T1.管理年月 = 200503 更新対象のレコードの抽出条件は「T1.管理年月 = 200503」だけで十分かと。 あとは、更新する値を抽出する方で、GROUP BYを使って単一行を返します。
お礼
ありがとうございます。これも出来ますね。 本当にいろいろやり方があるんだなと。 すごく勉強になりました。