回答編集履歴
1
データ構成が変わったことを受け、回答に追記しました。
answer
CHANGED
@@ -5,4 +5,63 @@
|
|
5
5
|
customer.連番 = changes.旧連番
|
6
6
|
changes.変更日 = (「旧連番、旧カード番号が同じデータの中で最大の変更日」を取得するサブクエリ);
|
7
7
|
```
|
8
|
-
サブクエリの書き方は色々とあると思うので、ご自身で考えてみて下さい。
|
8
|
+
サブクエリの書き方は色々とあると思うので、ご自身で考えてみて下さい。
|
9
|
+
|
10
|
+
---
|
11
|
+
↓↓↓追記↓↓↓
|
12
|
+
sazi様の回答にあるようにWITH RECURSIVEを使用する方法で解決できそうです。
|
13
|
+
```SQL
|
14
|
+
WITH RECURSIVE OKYAKUSAMA AS (
|
15
|
+
SELECT '0001' AS ID, 1 AS RENNBANN, '0001001' AS CARDNO
|
16
|
+
UNION
|
17
|
+
SELECT '0001' AS ID, 3 AS RENNBANN, '0001001' AS CARDNO
|
18
|
+
UNION
|
19
|
+
SELECT '0005' AS ID, 4 AS RENNBANN, '0001010' AS CARDNO
|
20
|
+
)
|
21
|
+
, HENNKOU AS (
|
22
|
+
SELECT '1001' AS ID, 1 AS RENNBANN, '1001003' AS CARDNO, '1001' AS KYUUID, 2 AS KYUURENNBANN, '1001003' AS KYUUCARDNO, TO_TIMESTAMP('2018/08/20 12:00:00', 'YYYY/MM/DD HH24:MI:SS') AS HENKOUBI
|
23
|
+
UNION
|
24
|
+
SELECT '1001' AS ID, 2 AS RENNBANN, '1001003' AS CARDNO, '0001' AS KYUUID, 3 AS KYUURENNBANN, '0001001' AS KYUUCARDNO, TO_TIMESTAMP('2018/08/01 11:00:00', 'YYYY/MM/DD HH24:MI:SS') AS HENKOUBI
|
25
|
+
UNION
|
26
|
+
SELECT '1005' AS ID, 5 AS RENNBANN, '1001005' AS CARDNO, '0005' AS KYUUID, 4 AS KYUURENNBANN, '0001010' AS KYUUCARDNO, TO_TIMESTAMP('2018/08/20 13:00:00', 'YYYY/MM/DD HH24:MI:SS') AS HENKOUBI
|
27
|
+
)
|
28
|
+
, TAISYO(ID, RENNBANN, CARDNO, MOTOID, MOTORENNBANN, MOTOCARDNO, DEPTH) AS (
|
29
|
+
SELECT CHANGES.ID, CHANGES.RENNBANN, CHANGES.CARDNO, CUSTOMER.ID AS MOTOID, CUSTOMER.RENNBANN AS MOTORENNBANN, CUSTOMER.CARDNO AS MOTOCARDNO, 1 AS DEPTH
|
30
|
+
FROM OKYAKUSAMA AS CUSTOMER
|
31
|
+
INNER JOIN HENNKOU AS CHANGES
|
32
|
+
ON CUSTOMER.ID = CHANGES.KYUUID
|
33
|
+
AND CUSTOMER.RENNBANN = CHANGES.KYUURENNBANN
|
34
|
+
AND CUSTOMER.CARDNO = CHANGES.KYUUCARDNO
|
35
|
+
UNION ALL
|
36
|
+
SELECT CHANGES.ID, CHANGES.RENNBANN, CHANGES.CARDNO, TAISYO.MOTOID, TAISYO.MOTORENNBANN, TAISYO.MOTOCARDNO, DEPTH + 1
|
37
|
+
FROM HENNKOU AS CHANGES, TAISYO
|
38
|
+
WHERE TAISYO.ID = CHANGES.KYUUID
|
39
|
+
AND TAISYO.RENNBANN = CHANGES.KYUURENNBANN
|
40
|
+
AND TAISYO.CARDNO = CHANGES.KYUUCARDNO
|
41
|
+
)
|
42
|
+
SELECT SUB_TAISYO.ID, SUB_TAISYO.RENNBANN, SUB_TAISYO.CARDNO
|
43
|
+
FROM OKYAKUSAMA, (
|
44
|
+
SELECT SUB.*
|
45
|
+
FROM (SELECT TAISYO.*, MAX(TAISYO.DEPTH) OVER(PARTITION BY TAISYO.MOTOID, TAISYO.MOTORENNBANN, TAISYO.MOTOCARDNO) MAX_DEPTH FROM TAISYO) SUB
|
46
|
+
WHERE SUB.DEPTH = SUB.MAX_DEPTH
|
47
|
+
) SUB_TAISYO
|
48
|
+
WHERE OKYAKUSAMA.ID = SUB_TAISYO.MOTOID
|
49
|
+
AND OKYAKUSAMA.RENNBANN = SUB_TAISYO.MOTORENNBANN
|
50
|
+
AND OKYAKUSAMA.CARDNO = SUB_TAISYO.MOTOCARDNO
|
51
|
+
```
|
52
|
+
|
53
|
+
WITH句のOKYAKUSAMAとHENNKOUはお客様TBLと変更情報TBLをインラインで表現しているだけなので読み飛ばして下さい。(当方の環境にテーブル作成するのが面倒であったので了承下さい。。)
|
54
|
+
TAISYOの部分がWITH RECURSIVEの構文を使用している部分です。
|
55
|
+
まず、非再帰的表現部分でお客様TBLのキーと変更情報TBLの旧キーが同じデータを抽出しています。ここで、お客様情報のキーを元キー(MOTOID, MOTORENNBANN, MOTOCARDNO)として保持しています。さらに、深さを表すDEPTHを1として定義しています。
|
56
|
+
再帰的表現部分では、非再帰的表現部分で取得できた結果の変更情報TBLのキーが変更情報TBLの旧キーと同じデータを抽出しており、これを繰り返します。繰り返すたびDEPTHは加算されます。
|
57
|
+
その結果は以下のようになります。
|
58
|
+
```SQLの結果
|
59
|
+
ID;RENNBANN;CARDNO;MOTOID;MOTORENNBANN;MOTOCARDNO;DEPTH
|
60
|
+
"1001";2;"1001003";"0001";3;"0001001";1
|
61
|
+
"1001";1;"1001003";"0001";3;"0001001";2
|
62
|
+
"1005";5;"1001005";"0005";4;"0001010";1
|
63
|
+
```
|
64
|
+
WITH以降のSELECT句でこの結果から**お客様TBLのキーと元キーが同じ、かつ、深さが最大のデータ**を取得すると更新対象とその更新値が取得できます。
|
65
|
+
|
66
|
+
他にもやり方はあるかと思いますが、私のつたないSQLではこれが限界でした。。。
|
67
|
+
わかりづらい部分が多いと思いますし、やり方はこれだけではないはずなので、ご自身に合った方法を見つけて課題解決下さい。
|