実現したいこと
ある契約情報を保管している実績履歴テーブルと取消履歴テーブルから
取消履歴テーブルの取消年月日を実績履歴テーブルの消込年月日に埋め込む
SQLを作成したいです。
お力添えいただけますと幸いです。
前提
1. 契約NO、契約年月日、金額が完全一致しているデータを抽出。
2. 完全一致の行が複数ある場合、「登録年月日」「登録時間」「明細NO」が小さいものから順に取消年月日を更新。
3. 実績履歴テーブルの取消年月日を取消履歴テーブルの取消年月日の値に更新。
実績履歴テーブル(一部抜粋)
契約NO | 契約年月日 | 取消年月日 | 金額 | 登録年月日 | 登録時間 | 明細NO |
---|---|---|---|---|---|---|
A1 | 2023/02/15 | NULL | 3,000 | 2023/02/15 | 170000 | 1 |
A1 | 2023/02/15 | NULL | 3,000 | 2023/04/05 | 170000 | 1 |
A1 | 2023/02/15 | NULL | 3,000 | 2023/04/05 | 180000 | 1 |
A1 | 2023/03/15 | NULL | 3,000 | 2023/03/15 | 170000 | 2 |
A1 | 2023/03/15 | NULL | 3,000 | 2023/04/05 | 170000 | 2 |
CREATE TABLE 実績履歴 ( 契約NO CHAR(20), 契約年月日 DATE, 取消年月日 DATE, 金額 NUMBER(11,0), 登録年月日 DATE, 登録時間 VARCHAR2(7), 明細NO NUMBER(3,0) ) / INSERT INTO 実績履歴 VALUES ('A1','2023/02/15',NULL,'3000','2023/02/15','170000','1') / INSERT INTO 実績履歴 VALUES ('A1','2023/02/15',NULL,'3000','2023/04/05','170000','1') / INSERT INTO 実績履歴 VALUES ('A1','2023/02/15',NULL,'3000','2023/04/05','180000','1') / INSERT INTO 実績履歴 VALUES ('A1','2023/03/15',NULL,'3000','2023/03/15','170000','2') / INSERT INTO 実績履歴 VALUES ('A1','2023/03/15',NULL,'3000','2023/04/05','170000','2') /
消込履歴テーブル(一部抜粋)
契約NO | 契約年月日 | 取消年月日 | 金額 | 明細NO |
---|---|---|---|---|
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 1 |
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 1 |
A1 | 2023/03/15 | 2023/04/05 | 3,000 | 2 |
CREATE TABLE 取消履歴 ( 契約NO CHAR(20), 契約年月日 DATE, 取消年月日 DATE, 金額 NUMBER(11,0), 明細NO NUMBER(3,0) ) / INSERT INTO 取消履歴 VALUES ('A1','2023/02/15','2023/04/05','3000','1') / INSERT INTO 取消履歴 VALUES ('A1','2023/02/15','2023/04/05','3000','1') / INSERT INTO 取消履歴 VALUES ('A1','2023/03/15','2023/04/05','3000','2') /
発生している問題
複数行あった場合に、更新対象の実績履歴テーブルが取得できず
間違った履歴に取消年月日が更新されてしまっている状態です。
FORでSELECTを回して更新データを抽出しているのですが
W_CNTの指定がおかしいと思われますがどう修正すればいいかわからず詰まってしまっています。
2. 完全一致の行が複数ある場合、「登録年月日」「登録時間」「明細NO」が小さいものから順に取消年月日を更新。
小さいものが取得できてません。
該当のソースコード
Object BrowserのPROCEDUREで以下処理を実行。
-- 取消情報抽出 FOR REC IN ( SELECT DISTINCT 取消.* FROM 取消履歴 取消 ,実績履歴 実績 WHERE 取消.契約NO = 実績.契約NO AND 取消.契約年月日 = 実績.契約年月日 AND 取消.金額 = 実績.金額 ) LOOP W_CNT := W_CNT + 1; -- 更新対象の実績履歴を抽出 FOR REC2 IN ( SELECT AAA.* FROM ( SELECT 実績.* ,ROW_NUMBER() OVER(ORDER BY 実績.登録年月日 ASC, 実績.登録時間 ASC, 実績.明細NO ASC ) AS 順番 FROM 実績履歴 実績 WHERE 実績.契約NO = REC.契約NO AND 実績.契約年月日 = REC.契約年月日 AND 実績.金額 = REC.金額 AND 実績.明細NO = REC.明細NO ) AAA WHERE 順番 = W_CNT ) LOOP -- 更新処理 UPDATE 実績履歴 UPD実績 SET UPD実績.取消年月日 = REC.取消年月日 WHERE UPD実績.契約NO = REC2.契約NO AND UPD実績.契約年月日 = REC2.契約年月日 AND UPD実績.金額 = REC2.金額 AND UPD実績.登録年月日 = REC2.登録年月日 AND UPD実績.登録時間 = REC2.登録時間 AND UPD実績.明細NO = REC2.明細NO ; END LOOP; END LOOP;
実行結果
〇誤
実際に更新された情報
契約NO | 契約年月日 | 取消年月日 | 金額 | 登録年月日 | 登録時間 | 明細NO |
---|---|---|---|---|---|---|
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 2023/02/15 | 170000 | 1 |
A1 | 2023/02/15 | NULL | 3,000 | 2023/04/05 | 170000 | 1 |
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 2023/04/05 | 180000 | 1 |
A1 | 2023/03/15 | NULL | 3,000 | 2023/03/15 | 170000 | 2 |
A1 | 2023/03/15 | 2023/04/05 | 3,000 | 2023/04/05 | 170000 | 2 |
〇正
本当はこのように更新されてほしい。
契約NO | 契約年月日 | 取消年月日 | 金額 | 登録年月日 | 登録時間 | 明細NO |
---|---|---|---|---|---|---|
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 2023/02/15 | 170000 | 1 |
A1 | 2023/02/15 | 2023/04/05 | 3,000 | 2023/04/05 | 170000 | 1 |
A1 | 2023/02/15 | NULL | 3,000 | 2023/04/05 | 180000 | 1 |
A1 | 2023/03/15 | 2023/04/05 | 3,000 | 2023/03/15 | 170000 | 2 |
A1 | 2023/03/15 | NULL | 3,000 | 2023/04/05 | 170000 | 2 |
調査したこと、試したこと
①W_CNT の指定方法をどうにかする必要あり。
②partition byを利用したら上手くいくかも?
ROW_NUMBER() OVER(ORDER BY 実績.登録年月日 ASC, 実績.登録時間 ASC, 実績.明細NO ASC ) AS 順番
良い方法ありますでしょうか?
ご教授のほどよろしくお願いいたします。

回答2件
あなたの回答
tips
プレビュー