プロが教える店舗&オフィスのセキュリティ対策術

管理テーブルというテーブルがあります。
フィールド構成は、会社コード(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.支店コード)

A 回答 (6件)

UPDATE 管理テーブル T1


SET T1.管理番号 = nvl((
SELECT DISTINCT T2.管理番号
FROM 管理テーブル T2
WHERE T2.会社コード = T1.会社コード AND
T2.支店コード = T1.支店コード AND
T2.管理年月 = 200502
), 00000000)
WHERE T1.管理年月 = 200503

これではどうでしょうか?
    • good
    • 0
この回答へのお礼

ありがとうございます。これも出来ますね。
本当にいろいろやり方があるんだなと。
すごく勉強になりました。

お礼日時:2005/03/30 10:48

#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の管理番号で更新されるハズです。

なので、事態が理解できないカンジです。
    • good
    • 0
この回答へのお礼

ありがとうございました。
このSQLでうまく行きました。結構こういう変なファイル
が多いので今後活用させて頂きます。
とても勉強になりました。

お礼日時:2005/03/30 10:43

#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に集計関数付け忘れました。
    • good
    • 0
この回答へのお礼

ありがとうございました。エラーもなく更新件数がぴったり合ったので出来た!と喜びましたが、
結果を見ると管理番号が全て0000000に置き換わってしまいました。これはやばい!です。

お礼日時:2005/03/29 17:33

レコード(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.支店コード)
    • good
    • 0
この回答へのお礼

ありがとうございました。エラーもなく更新件数がぴったり合ったので出来た!と喜びましたが、
結果を見ると管理番号が全て0000000に置き換わってしまいました。これはやばい!です。

お礼日時:2005/03/29 17:41

間違ってるかもしれませんが・・・。



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
            )
こんな感じでどうでしょう。
    • good
    • 0
この回答へのお礼

ありがとうございました。参考にさせて頂きました。
でも T2.管理年月 = 200502でエラーが出てしまいました。思うに管理年月が選択されていないからでは・・

お礼日時:2005/03/29 17:22

これでどうかな?



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を使って単一行を返します。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す