我有两个具有相同列的表。如果发生更改,则会将其记录在table2
中,然后我将table1
与table2
进行比较,看看它们是否不同。如果它们不同,我总结说有一个改变,我想在我的结果表中显示它。
例如:
SELECT t1.name, t1.age, t1.profession, column_changed, old_value, new_value
FROM table1 t1, table2 t2
WHERE t1.column1<>t2.column1
OR t1.column2<>t2.column2
OR t1.column3<>t2.column3
当然这个查询不正确。我希望column_changed
,old_value
,new_value
显示相关值。
有什么想法吗?
答案 0 :(得分:2)
Age,name,profession是否构成主键(或至少是唯一的键?):
如果是这样,你可以这样做:
SELECT
t1.name, t1.age, t1.profession,
t1.column1 as t1column1, t2.column1 as t2column1,
t1.column2 as t1column2, t2.column2 as t2column2,
FROM
table1 t1, table2 t2
WHERE
(t1.name = t2.name and t1.age = t2.age and t1.profession = t2.profession) and
(
t1.column1<>t2.column1
OR t1.column2<>t2.column2
OR t1.column3<>t2.column3)
当然,这需要一个唯一的密钥,在两个表中都是相同的。此外,我清楚地更改了查询的结果,以显示所有列,而不仅仅是更改的列。识别在单个T-SQL查询中改变的那个是笨拙的(但可能),所以我的建议是这样返回它并根据你的用例让应用程序/表示层处理找到哪个列发生了变化或只是扫描用眼睛看。
如果您真的想在T-SQL中使用它,可以使用UNIONS,例如:
SELECT
t1.name, t1.age, t1.profession,
'column1' as ColumnChanged,
t1.column1 as oldValue,
t2.column1 as newValue
FROM
table1 t1, table2 t2
WHERE
(t1.name = t2.name and t1.age = t2.age and t1.profession = t2.profession) and
t1.column1<>t2.column1
UNION ALL #better peformance than UNION, which would enforce uniqueness
SELECT
t1.name, t1.age, t1.profession,
'column2' as ColumnChanged,
t1.column2 as oldValue,
t2.column2 as newValue
FROM
table1 t1, table2 t2
WHERE
(t1.name = t2.name and t1.age = t2.age and t1.profession = t2.profession) and
t1.column2<>t2.column2
.......
答案 1 :(得分:1)
试试这个:
Select t1.name, t1.age, t1.profession,
case when t1.column1 <> t2.column1 then 'column1 changed'
when t1.column2 <> t2.column2 then 'column2 changed'
-- and so on...
end as [column_changed],
case when t1.column1 <> t2.column1 then t1.column1
when t1.column2 <> t2.column2 then t1.column2
-- and so on...
end as [old_value],
case when t1.column1 <> t2.column1 then t2.column1
when t1.column2 <> t2.column2 then t2.column2
-- and so on...
end as [new_value]
From table1 t1, table2 t2
Where t1.column1 <> t2.column1
Or t1.column2 <> t2.column2
Or t1.column3 <> t2.column3
答案 2 :(得分:1)
经过进一步的脑力激荡后,我得出结论,甘露解决方案可以通过轻微的改进更好地工作。改进是while循环和count变量。如果有多个列同时更改而不只是一个,我们需要这样做。但是,它会导致输出NULL,因此您可以删除它们。这是修改过的查询:
WHILE @count<3
BEGIN
Select t1.name, t1.age, t1.profession,
case when t1.column1 <> t2.column1 and @count = 1 then 'column1 changed'
when t1.column2 <> t2.column2 @count = 2 then 'column2 changed'
-- and so on...
end as [column_changed],
case when t1.column1 <> t2.column1 @count = 1 then t1.column1
when t1.column2 <> t2.column2 @count = 2 then t1.column2
-- and so on...
end as [old_value],
case when t1.column1 <> t2.column1 @count = 1 then t2.column1
when t1.column2 <> t2.column2 @count = 2 then t2.column2
-- and so on...
end as [new_value]
From table1 t1, table2 t2
Where t1.column1 <> t2.column1 Or t1.column2 <> t2.column2 Or t1.column3 <> t2.column3
SET @counter = @counter + 1
END
答案 3 :(得分:1)
这是您的解决方案被重写为单个SELECT语句(或者,如果您愿意,@ ganders被重写为支持同一行中的多个更改):
SELECT
x.column_changed,
t1.column1 AS old_value,
t2.column1 AS new_value
FROM table1 t1
INNER JOIN table2 t2 ON t1.name = t2.name
INNER JOIN (
SELECT 'column1' UNION ALL
SELECT 'column2' UNION ALL
…
) x (column_changed) ON (
x.column_changed = 'column1' AND t1.column1 <> t2.column1 OR
x.column_changed = 'column2' AND t1.column2 <> t2.column2 OR
…
)
答案 4 :(得分:0)
我使用名称列在您的查询中添加了加入@ T2 t2 on t2.name = t1.name 。假设它可用于链接两个表之间的记录。
select
t1.name, t1.age, t1.profession,
column_change =
case when t1.column1 <> t2.column1 then 'column1'
when t1.column2 <> t2.column2 then 'column2'
when t1.column3 <> t2.column3 then 'column3'
end,
old_value =
case when t1.column1 <> t2.column1 then t1.column1
when t1.column2 <> t2.column2 then t1.column2
when t1.column3 <> t2.column3 then t1.column3
end,
new_value =
case when t1.column1 <> t2.column1 then t2.column1
when t1.column2 <> t2.column2 then t2.column2
when t1.column3 <> t2.column3 then t2.column3
end
from @T1 t1
join @T2 t2 on t2.name = t1.name
where
(t1.column1 <> t2.column1
or t1.column2 <> t2.column2
or t1.column3 <> t2.column3)