我有一个这样的桌子
ID | FatherID | A | B | C | D | ...
1234 | -1 | John | Doe | 15 | 20181211 | ...
5678 | -1 | Mark | Bloch | 34 | 20170804 | ...
4554 | 1234 | John | Dee | 25 | 20181211 | ...
2457 | 5678 | Chris| Bloch | 34 | 20180402 | ...
如果对给定对象进行了修改(例如ID 1234),则系统会参考原始ID(FatherID = 1234)将新版本数据存储在新ID(例如4554)上。 系统仅存储初始版本和主要修订(最后修改),例如,如果最终再次修改4554,则不会创建新记录,但会更新4554值->每个ID最多2条记录
有很多列(大约400列)...
我想以这样的格式列出所做的修改:
ID | Field | Before | After
4554 | B | Doe | Dee
4554 | C | 15 | 25
2457 | A | Mark | Chris
4554 | D | 20170804 | 20180402
我正在努力做到这一点,特别是考虑到列数。
任何帮助将不胜感激!
非常感谢
答案 0 :(得分:0)
有很多列(大约400列)...
仅向您介绍一下仅检查4列的情况(这是针对Oracle):
WITH full AS (
SELECT
o.ID,
o.A, o.B, o.C, o.D,
n.A AS newA, n.B AS newB, n.C AS newC, n.D AS newD
FROM tablename o
INNER JOIN tablename n ON n.FatherID = o.ID
WHERE o.FatherID = -1
)
SELECT ID, Field, Before, After FROM(
SELECT
ID,
'A' As Field,
CASE WHEN A <> newA THEN 1 ELSE 0 END AS changed,
A AS Before,
newA AS After
FROM full
UNION
SELECT
ID,
'B' As Field,
CASE WHEN B <> newB THEN 1 ELSE 0 END AS changed,
B AS Before,
newB AS After
FROM full
UNION
SELECT
ID,
'C' As Field,
CASE WHEN C <> newC THEN 1 ELSE 0 END AS changed,
C AS Before,
newC AS After
FROM full
UNION
SELECT
ID,
'D' As Field,
CASE WHEN D <> newD THEN 1 ELSE 0 END AS changed,
D AS Before,
newD AS After
FROM full
)
WHERE changed = 1
答案 1 :(得分:0)
您可以取消对配对列的过滤,并仅过滤不同的列。
select id, fatherid, field, o before, n after
from (
select n.id, n.fatherid, n.a na, o.a oa, n.b nb, o.b ob,
to_char(n.c) nc, to_char(o.c) oc,
to_char(n.d) nd, to_char(o.d) od
from t n join t o on n.fatherid = o.id)
unpivot ((n, o) for field in ((na, oa) as 'A', (nb, ob) as 'B',
(nc, oc) as 'C', (nd, od) as 'D'))
where n <> o or (n is null and o is not null) or (n is not null and o is null)
order by id, field
ID FATHERID FIELD BEFORE AFTER
------ --------- ----- -------- -----------
2457 5678 A Mark Chris
2457 5678 D 20170804 20180402
4554 1234 B Doe Dee
4554 1234 C 15 25
您必须列出所有列,并将它们转换为char。很多工作,很多错误空间,但这是我想出的最好的方法。