1

嗨,我有两个表 Test1 和 Test2。

一个是另一个的副本,因此它们具有相同的列(ID、LastDiaryEvent、Impact、Prority、Status、Name)和值。Test1 获取更新并更改其中一列中的值(例如,状态)。

我知道比较两个表的代码

select * from Test1
except
select * from Test2;

但这会带回整行,我需要指定已更改的值。

所以,

测试1 + 测试2

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为例,只有ID值不会改变,

有没有办法做到这一点?

谢谢

4

3 回答 3

1

有几种情况需要检查

  • 表 2 中的新行
  • 表 2 中删除的行
  • 表 2 中的更改值或值

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

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

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
于 2013-07-04T15:19:34.393 回答
0

假设 ID 永远不会改变,我认为 aJOINCASE是合适的:

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', ''
于 2013-07-04T15:10:15.227 回答
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 上加入......您可能希望/需要根据您的数据模型要求加入更多内容。

于 2013-07-04T15:02:28.940 回答