我正在比较2张桌子。一个有新数据,另一个有上个月的旧数据。数据每月发布一次,每次都是数据。没有PK,任何字段都可以改变。我需要显示更改记录的字段和旧值。它可以是1个或多个字段。为此,我创建了内连接,其中所有字段都连接在一起,除了1然后在我说旧值不等于新值的地方然后我添加2列,告诉我我们正在查看哪个字段以及旧的价值是。我对每个字段执行此查询并将结果合并,因此我的最终表格如下所示:
FieldA, FieldB, FieldC, FieldChanged, OldValue
FieldChanged将为该记录更改字段名称,OldValue将说明旧值是什么。
如果记录中有多个字段已更改(有),那么我会在结果中复制字段A-C,并使用不同的FieldChanged和OldValue值。但是,我想通过FieldA,FieldB,FieldC做一个小组,并以某种方式联系所有相同记录中的FieldChanged和来自所有相同记录的OldValue。
联合查询结果看起来像(前三个字段是新数据的样子):
"Tiger", "74", "Masters", "FieldC", "The Masters"
"Tiger", "74", "Masters", "FieldB", "68"
我想按字段1-3进行分组,然后连接组中的最后两个字段:
"Tiger", "74", "Masters", "FieldB,FieldC", "68,The Masters"
现在这只是一个例子,所以它很简单,可能很容易说这是一个新的记录,但是我的表有12个字段,所以如果一切都匹配但只有1个字段,很可能它是相同的记录,他们只是更新了一个的领域。
此处的关键是能够按某些列进行分组,并将分组列中的其他字段值连接在一起,以便不重复相同的记录,并且我有1行显示已为该记录更改的每个字段,它是旧的价值观。
答案 0 :(得分:2)
试试这个。
CREATE TABLE #test
(
FieldA VARCHAR(25),
FieldB VARCHAR(25),
FieldC VARCHAR(25),
FieldChanged VARCHAR(25),
OldValue VARCHAR(25)
)
INSERT #test
VALUES ('Tiger','74','Masters','FieldC','The Masters'),
('Tiger','74','Masters','FieldB','68')
方法1:适用于XML PATH
SELECT my_column AS [text()]
FROM my_table
FOR XML PATH('')
这为您提供了表
中此列的所有值的连接值SELECT FieldA,
FieldB,
FieldC,
Stuff((SELECT ', ' + FieldChanged
FROM #test b
WHERE b.FieldA = a.FieldA
AND b.FieldB = a.FieldB
AND b.FieldC = a.FieldC
FOR XML PATH('')), 1, 2, '') FieldChanged,
Stuff((SELECT ', ' + OldValue
FROM #test b
WHERE b.FieldA = a.FieldA
AND b.FieldB = a.FieldB
AND b.FieldC = a.FieldC
FOR XML PATH('')), 1, 2, '') OldValue
FROM #test a
GROUP BY FieldA,
FieldB,
FieldC
方法2:使用Cross Apply
SELECT FieldA,
FieldB,
FieldC,
Substring(d.FieldChanged, 1, Len(d.FieldChanged) - 1) FieldChanged,
Substring(d.OldValue, 1, Len(d.OldValue) - 1) OldValue
FROM (SELECT DISTINCT FieldA,
FieldB,
FieldC
FROM #test) a
CROSS APPLY (SELECT (SELECT FieldChanged + ', '
FROM #test AS B
WHERE b.FieldA = a.FieldA
AND b.FieldB = a.FieldB
AND b.FieldC = a.FieldC
FOR XML PATH('')),
(SELECT OldValue + ', '
FROM #test AS B
WHERE b.FieldA = a.FieldA
AND b.FieldB = a.FieldB
AND b.FieldC = a.FieldC
FOR XML PATH(''))) D (FieldChanged, OldValue)