回答編集履歴

1

データ構成が変わったことを受け、回答に追記しました。

2018/08/28 06:39

投稿

SE-studying-now
SE-studying-now

スコア351

test CHANGED
@@ -13,3 +13,121 @@
13
13
  ```
14
14
 
15
15
  サブクエリの書き方は色々とあると思うので、ご自身で考えてみて下さい。
16
+
17
+
18
+
19
+ ---
20
+
21
+ ↓↓↓追記↓↓↓
22
+
23
+ sazi様の回答にあるようにWITH RECURSIVEを使用する方法で解決できそうです。
24
+
25
+ ```SQL
26
+
27
+ WITH RECURSIVE OKYAKUSAMA AS (
28
+
29
+ SELECT '0001' AS ID, 1 AS RENNBANN, '0001001' AS CARDNO
30
+
31
+ UNION
32
+
33
+ SELECT '0001' AS ID, 3 AS RENNBANN, '0001001' AS CARDNO
34
+
35
+ UNION
36
+
37
+ SELECT '0005' AS ID, 4 AS RENNBANN, '0001010' AS CARDNO
38
+
39
+ )
40
+
41
+ , HENNKOU AS (
42
+
43
+ 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
44
+
45
+ UNION
46
+
47
+ 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
48
+
49
+ UNION
50
+
51
+ 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
52
+
53
+ )
54
+
55
+ , TAISYO(ID, RENNBANN, CARDNO, MOTOID, MOTORENNBANN, MOTOCARDNO, DEPTH) AS (
56
+
57
+ SELECT CHANGES.ID, CHANGES.RENNBANN, CHANGES.CARDNO, CUSTOMER.ID AS MOTOID, CUSTOMER.RENNBANN AS MOTORENNBANN, CUSTOMER.CARDNO AS MOTOCARDNO, 1 AS DEPTH
58
+
59
+ FROM OKYAKUSAMA AS CUSTOMER
60
+
61
+ INNER JOIN HENNKOU AS CHANGES
62
+
63
+ ON CUSTOMER.ID = CHANGES.KYUUID
64
+
65
+ AND CUSTOMER.RENNBANN = CHANGES.KYUURENNBANN
66
+
67
+ AND CUSTOMER.CARDNO = CHANGES.KYUUCARDNO
68
+
69
+ UNION ALL
70
+
71
+ SELECT CHANGES.ID, CHANGES.RENNBANN, CHANGES.CARDNO, TAISYO.MOTOID, TAISYO.MOTORENNBANN, TAISYO.MOTOCARDNO, DEPTH + 1
72
+
73
+ FROM HENNKOU AS CHANGES, TAISYO
74
+
75
+ WHERE TAISYO.ID = CHANGES.KYUUID
76
+
77
+ AND TAISYO.RENNBANN = CHANGES.KYUURENNBANN
78
+
79
+ AND TAISYO.CARDNO = CHANGES.KYUUCARDNO
80
+
81
+ )
82
+
83
+ SELECT SUB_TAISYO.ID, SUB_TAISYO.RENNBANN, SUB_TAISYO.CARDNO
84
+
85
+ FROM OKYAKUSAMA, (
86
+
87
+ SELECT SUB.*
88
+
89
+ FROM (SELECT TAISYO.*, MAX(TAISYO.DEPTH) OVER(PARTITION BY TAISYO.MOTOID, TAISYO.MOTORENNBANN, TAISYO.MOTOCARDNO) MAX_DEPTH FROM TAISYO) SUB
90
+
91
+ WHERE SUB.DEPTH = SUB.MAX_DEPTH
92
+
93
+ ) SUB_TAISYO
94
+
95
+ WHERE OKYAKUSAMA.ID = SUB_TAISYO.MOTOID
96
+
97
+ AND OKYAKUSAMA.RENNBANN = SUB_TAISYO.MOTORENNBANN
98
+
99
+ AND OKYAKUSAMA.CARDNO = SUB_TAISYO.MOTOCARDNO
100
+
101
+ ```
102
+
103
+
104
+
105
+ WITH句のOKYAKUSAMAとHENNKOUはお客様TBLと変更情報TBLをインラインで表現しているだけなので読み飛ばして下さい。(当方の環境にテーブル作成するのが面倒であったので了承下さい。。)
106
+
107
+ TAISYOの部分がWITH RECURSIVEの構文を使用している部分です。
108
+
109
+ まず、非再帰的表現部分でお客様TBLのキーと変更情報TBLの旧キーが同じデータを抽出しています。ここで、お客様情報のキーを元キー(MOTOID, MOTORENNBANN, MOTOCARDNO)として保持しています。さらに、深さを表すDEPTHを1として定義しています。
110
+
111
+ 再帰的表現部分では、非再帰的表現部分で取得できた結果の変更情報TBLのキーが変更情報TBLの旧キーと同じデータを抽出しており、これを繰り返します。繰り返すたびDEPTHは加算されます。
112
+
113
+ その結果は以下のようになります。
114
+
115
+ ```SQLの結果
116
+
117
+ ID;RENNBANN;CARDNO;MOTOID;MOTORENNBANN;MOTOCARDNO;DEPTH
118
+
119
+ "1001";2;"1001003";"0001";3;"0001001";1
120
+
121
+ "1001";1;"1001003";"0001";3;"0001001";2
122
+
123
+ "1005";5;"1001005";"0005";4;"0001010";1
124
+
125
+ ```
126
+
127
+ WITH以降のSELECT句でこの結果から**お客様TBLのキーと元キーが同じ、かつ、深さが最大のデータ**を取得すると更新対象とその更新値が取得できます。
128
+
129
+
130
+
131
+ 他にもやり方はあるかと思いますが、私のつたないSQLではこれが限界でした。。。
132
+
133
+ わかりづらい部分が多いと思いますし、やり方はこれだけではないはずなので、ご自身に合った方法を見つけて課題解決下さい。