您好我有两张表Test1和Test2。
一个是另一个的副本,因此它们具有相同的列(ID,LastDiaryEvent,Impact,Prority,Status,Name)和值。 Test1获取更新并更改其中一列中的值(例如,以状态为例)。
我知道比较两个表的代码
select * from Test1
except
select * from Test2;
但这会带回整行,我需要指定已更改的值已更改。
所以,
TEST1 + TEST2
ID LastDiaryEvent Impact Priority Status Name
277199 2013-07-10 Problem Standard Customer BAILEYB
然后更新TEST1表,以便行读取
ID LastDiaryEvent Impact Priority Status Name
277199 2013-07-10 Problem Standard Action BAILEYB
因此状态值已更改。我可以比较这两行,但想知道如何指定它是已更改的Status值。注意,我使用Status作为示例,只有ID值不会被更改,
有办法做到这一点吗?
由于
答案 0 :(得分:1)
有几种情况需要检查
注意最后一位:有几个值可能会改变。
此代码返回一系列标志以显示 已更改的内容
CREATE TABLE #test1 (ID int, Impact varchar(100), NAME varchar(100), STATUS char(1));
CREATE TABLE #test2 (ID int, Impact varchar(100), NAME varchar(100), STATUS char(1));
GO
INSERT #test1 VALUES (1, 'xx', 'name1', 'A'), (2, 'zz', 'name2', 'B'), (3, 'xx', 'name3', 'B'), (4, 'xx', 'name4', 'A');
INSERT #test2 VALUES (1, 'xx', 'name1', 'A'), /*(2, 'xx', 'name2', 'B'),*/ (3, 'xx', 'name33', 'B'), (4, 'yy', 'name4', 'A'), (5, 'zz', 'name5', 'B');
GO
SELECT
0 AS MissingRowinT2,
0 AS NewRowinT2,
CASE WHEN T1.STATUS <> T2.STATUS THEN 1 ELSE 0 END AS StatusChanged,
CASE WHEN T1.NAME <> T2.NAME THEN 1 ELSE 0 END AS NAMEChanged,
CASE WHEN T1.Impact <> T2.Impact THEN 1 ELSE 0 END AS ImpactChanged,
*
FROM
#test1 T1
JOIN
#test2 T2 ON T1.ID = T2.ID
WHERE NOT EXISTS
(
select T1.*
INTERSECT
select T2.*
)
UNION ALL
SELECT
SIGN(ISNULL(T2.ID, 1)), SIGN(ISNULL(T1.ID, 1)), 0, 0, 0, *
FROM
#test1 T1
FULL OUTER JOIN
#test2 T2 ON T1.ID = T2.ID
WHERE
T1.ID IS NULL OR T2.ID IS NULL
GO
如果您需要拼写
SELECT
SUBSTRING(
CASE WHEN T1.STATUS <> T2.STATUS THEN ',Status' ELSE '' END +
CASE WHEN T1.NAME <> T2.NAME THEN ',NAME,' ELSE '' END +
CASE WHEN T1.Impact <> T2.Impact THEN ',Impact' ELSE '' END,
2, 8000) AS WhatCHanged,
*
FROM
#test1 T1
JOIN
#test2 T2 ON T1.ID = T2.ID
WHERE NOT EXISTS
(
select T1.*
INTERSECT
select T2.*
)
UNION ALL
SELECT
CASE WHEN T1.ID IS NULL THEN 'NewRow' ELSE 'Deleted Row' END, *
FROM
#test1 T1
FULL OUTER JOIN
#test2 T2 ON T1.ID = T2.ID
WHERE
T1.ID IS NULL OR T2.ID IS NULL
GO
答案 1 :(得分:0)
这将有效:
SELECT 'Status Change' as Change, t1.*
FROM table1 t1
JOIN table2 t2 on t1.ID = t2.ID
WHERE t1.Status != t2.Status
UNION ALL
SELECT 'LastDiaryEvent Change' as Change, t1.*
FROM table1 t1
JOIN table2 t2 on t1.ID = t2.ID
WHERE t1.LastDiaryEvent != t2.LastDiaryEvent
UNION ALL
SELECT 'Priority Change' as Change, t1.*
FROM table1 t1
JOIN table2 t2 on t1.ID = t2.ID
WHERE t1.Priority != t2.Priority
就像这样:
SELECT CASE WHEN t1.Status != t2.Status THEN 'Status Change'
WHEN t1.LastDiaryEvent != t2.LastDiaryEvent) THEN 'LastDiaryEvent Change'
WHEN t1.Priority != t2.Priority THEN 'Priority Change'
ELSE 'Panic!'END AS Chanage, t1.*
FROM table1 t1
JOIN table2 t2 on t1.ID = t2.ID
WHERE t1.Status != t2.Status OR
t1.LastDiaryEvent != t2.LastDiaryEvent OR
t1.Priority != t2.Priority
注意 - 我只加入ID = ID ...您可能需要/需要加入更多内容,因为您的数据模型需要。
答案 2 :(得分:0)
假设ID永远不会更改,我认为JOIN
和CASE
是合适的:
SELECT
(SELECT CASE WHEN t1.LastDiaryEvent <> t2.LastDiaryEvent
THEN 'diary event changed' ELSE '' END),
(SELECT CASE WHEN t1.Impact <> t2.Impact
THEN 'impact changed' ELSE '' END),
(SELECT CASE WHEN t1.Priority <> t2.Priority
THEN 'priority changed' ELSE '' END)
(SELECT CASE WHEN t1.Status <> t2.Status
THEN 'status changed' ELSE '' END)
(SELECT CASE WHEN t1.Name <> t2.Name
THEN 'name changed' ELSE '' END)
FROM Test1 t1
INNER JOIN Test2 t2 ON (Test1.ID = Test2.ID)
您的示例将返回:
'', '', '', 'status changed', ''