我想比较两张桌子。我们的程序的工作方式是,如果一个人被更改,它会更新记录并将原始数据抛出到新表中。
我能够创建一个有效的查询。但是,它只返回已更改的行。不知何故,我需要它来返回旧的和新的,并指出改变了什么。有没有办法做到这一点?
所以在这个例子中,在那里抛出另一个东西(对不起)Jon Doe不应该出现,因为没有真正改变。他的一个电话号码从一个电话领域转移到另一个电话领域。有这么多像这样,我的新版本仍然没有正确处理它们。
Jane应该出现,因为她的电子邮件发生了变化。然而,它只是返回该记录。我看不出改变了什么,或原始价值是什么。
无论哪种方式都必须说出类似的话。 (我会跳过细节)但是以某种格式让他们可以看到改变了什么。
Creating 4
Creating 3
Creating 2
Creating 1
Creating 0
康拉德的ETA变更(谢谢)
BEFORE AFTER CHANGED
Name: Jane Smith Jane Smith
Address: 111 East Grove 111 East Grove
Etc.
Email: janeR@gmail.com janes@gmail.com Yes
答案 0 :(得分:0)
您的问题与How can I write a query to extract individual changes from snapshots of data?之间的主要区别在于您只有两条记录可以竞争而不是N条记录。此外,您似乎想要所有值,但想知道它们是否已更改。
;with data as (
SELECT *
FROM [#Source] [S]
INNER JOIN [#Target] [T]
ON [S].[ID] = [T].[pov_Prospect]
)
, fieldsToRows
AS (SELECT
id,
field,
Value
FROM data p UNPIVOT (value FOR field IN (nameFull, pov_nameFull,
salutation, pov_salutation,
nameFirst, pov_nameFirst,
nameLast, pov_nameLast,
addressLine1, pov_addressLine1,
addressLine2, pov_addressLine2,
addressCity, pov_addressCity,
addressState, pov_addressState,
addressZip, pov_addressZip,
phone1full, pov_phone1full,
phone2full, pov_phone2full,
phone3full, pov_phone3full,
phone4full, pov_phone4full,
phone5full, pov_phone5full,
email1, pov_email1 ) )
AS unpvt
)
SELECT
curr.id,
curr.field,
curr.value new_value,
prev.value old_value,
CASE WHEN curr.value <> prev.value THEN 'Yes' END Changed
FROM
fieldsToRows curr
INNER JOIN fieldsToRows prev
ON curr.ID = prev.id
AND 'pov_' + curr.field = prev.field
由于您的数据为空,因此您必须与Handle NULL value in UNPIVOT抗争
在我的演示中,我将ISNULL添加到每个字段中,但为了简洁起见,将其留在上面
如果您想要消除没有变化的行,您需要添加一系列OR条款,例如ISNULL( s.nameFull, '') <> ISNULL( t.pov_nameFull, '')
请参阅Demo
这并不涉及移动的字段。为此,您需要做一些事情OR (phone1 <> pov_phone1 and phone1 <> pov_phone2 AND... ) OR
我将如何处理不同的数据类型(你的所有varchar(50))留给你
答案 1 :(得分:0)
我是从Conrad Frix的回答开始的,但是我将源代码和目标分开了,所以我们也可以找到涉及空值的差异:
;with SourceFieldsToRows AS (
SELECT id, field, Value
FROM #Source s UNPIVOT (Value FOR field IN (nameFull, salutation, nameFirst, nameLast, addressLine1, addressLine2, addressCity, addressState, addressZip, phone1full, phone2full, phone3full, phone4full, phone5full, email1)) u
), TargetFieldsToRows AS (
SELECT u.pov_Prospect, field, Value
FROM #Target t UNPIVOT (Value FOR field IN (pov_nameFull, pov_salutation, pov_nameFirst, pov_nameLast, pov_addressLine1, pov_addressLine2, pov_addressCity, pov_addressState, pov_addressZip, pov_phone1full, pov_phone2full, pov_phone3full, pov_phone4full, pov_phone5full, pov_email1)) u
)
SELECT ISNULL(curr.id,prev.pov_Prospect) AS id,
ISNULL(curr.field,prev.field) AS field,
curr.value AS new_value,
prev.value AS old_value,
CASE WHEN curr.value <> prev.value OR curr.value IS NULL AND prev.value IS NOT NULL OR curr.value IS NOT NULL AND prev.value IS NULL THEN 'Yes' END Changed
FROM SourceFieldsToRows curr
FULL OUTER JOIN TargetFieldsToRows prev
ON curr.ID = prev.pov_Prospect AND 'pov_' + curr.field = prev.field