比较两个表并突出显示不同的值

时间:2013-07-04 14:52:37

标签: sql

您好我有两张表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值不会被更改,

有办法做到这一点吗?

由于

3 个答案:

答案 0 :(得分:1)

有几种情况需要检查

  • table2中的新行
  • 已删除table2中的行
  • 更改了table2
  • 中的值或值

注意最后一位:有几个值可能会改变。

此代码返回一系列标志以显示 已更改的内容

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永远不会更改,我认为JOINCASE是合适的:

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', ''