我在SQL Server中有两个学生表,一个来自原始运行的基表和来自下一天运行的新表。每个表都有像Building,UserID LastName FirstName:
之类的信息基础表:
3 2509381 Brooks Corey
3 2527352 Doss Dawone
14 170163 Belin Teaira
14 2465666 Arlington Xavier
14 2465941 Smith Jerald
14 2466022 Junious Dontrell
14 2466898 Shelton Rayonna
14 2468144 Sullivan James
14 2468612 Brown Jerron
14 2469949 Quinn Jordan
新表:
3 2527352 Doss Dawone
14 170163 Belin Teaira
14 2465666 Arlington Xavier
14 2465941 Smith Jerald
14 2466022 Junious Dontrell
14 2466898 Shelton Rayonna
14 2468144 Sullivan James
14 2468612 Brown Jerron
3 2469949 Quinn Jordan
14 1234512 Davis John
在我的例子中,Brooks被删除了,Quinn修改了建筑物编号,并且添加了戴维斯,我希望我的结果表看起来像这样。
审核表:
3 2509381 Brooks Corey
14 2469949 Quinn Jordan
14 1234512 Davis John
我使用两个除了查询,以获得这些结果
选择* 来自test1 除了 选择 * 来自test2
3 2509381 Brooks Corey
14 2469949 Quinn Jordan
选择* 来自test2 除了 选择 * 来自test1
3 2469949 Quinn Jordan
14 1234512 Davis John
如何让它们输出审计表中的所有增量。我尝试联合我的两个选择语句,但这不起作用......
答案 0 :(得分:0)
我假设学生人数是独一无二的?或者,如果您还没有提供所有列,则有一些方法可以确定哪个是唯一的行。你需要这个,否则你无法检测到什么是新的和改变了什么。或者删除和添加的内容。
通常我们会使用一个将项目连接在一个唯一字段上的查询,在这种情况下可能是UserID。然后,您的联接需要比较其他各个字段。
外部联接将告诉您是否有关于插入和删除的信息。例如,我可以这样做:
select *
from base b
full outer join new n
on b.userid = n.userid
如果你这样做,那么你会看到各种各样的事情。如果b.userid但不是n.userid存在NULL,则新表中的新行不存在于基表中。如果您反过来,那么您已经删除了。对于更改,您可以比较每列的值,然后确定不同的列。您可以选择在几个查询中处理此问题,每个查询都查找单独的内容,例如插入查询,删除查询和更改查询。您可以将这些组合在一起,以获得可以插入审计表的结果帽。
注意:在许多系统中,我们会使用触发器实时捕获这些更改以进行审核(或SQL Server中的其他审核机制)。
答案 1 :(得分:0)
一种方法是构建异常查询,并使用插入新表来捕获数据:
创建表mytable_audit (Building,UserID,Lastname,Firstname,Audit_Date)
Insert into mytable_audit
Select Building, UserID, Lastname, Firstname, getdate() from mytable2
EXCEPT
Select Building, UserID, Lastname, Firstname, getdate() from mytable
该方法的唯一问题是它不会告诉您为什么数据在表中。您可以通过将其作为子查询来解决此问题(以wayOutwest表示您拥有唯一键的方式提供),然后重新连接到源表。这样您就可以添加一个case语句来提供指标。 最后,第二个查询的UNION检查已删除的学生:
Create table mytable_audit
(Building int, Username int, Lastname varchar(100), Firstname varchar(100), Audit_Date datetime, ChangeType varchar(100))
Insert into mytable_audit
Select aa.*, getdate(),
case when aa.building<>mt.building then 'Building Changed'
when mt.userid is null then 'Student Added'
when aa.lastname<>mt.lastname or aa.firstname<>mt.firstname then 'Student Name Changed'
end as changetype
from
(Select Building, UserID, Lastname, Firstname from mytable2
EXCEPT
Select Building, UserID, Lastname, Firstname from mytable) aa
left join mytable mt on aa.userID=mt.userID
UNION
Select Building, UserID, Lastname, Firstname, getdate(), 'Student Removed' from mytable mt
left join mytable2 mt2 on mt.userid=mt2.userid
where mt2.userid is null