SQL Server将类似的表与查询进行比较

时间:2010-09-13 15:50:36

标签: sql sql-server sql-server-2008 analysis

简单的概念我们基本上做了一些审计,比较了进来的内容,以及处理过程中实际发生的事情。我正在寻找一种更好的方法来执行一个查询,该查询可以与名称和潜在类型略有不同的列进行并排表比较。

数据库布局:

表(*是连接条件)

记录(未更改的数据记录。)
- LogID
- RecordID *
- 姓名
- 日期
- 地址
- 产品
- 等

审核(后处理记录)
- CardID *
- CarName
- 部署日期
- ShippingAddress
- 选项
- 等

例如,如果你看一下令人讨厌的写作复杂性和性能问题,这个工作。

查询只是左右连接并选择它们作为字符串。显示每个字段匹配。

select 
  cast(log.RecordID as varchar(40)) + '=' + cast(audit.CardID as varchar(40),
  log.Name+ '=' + audit.Name ,
  cast(log.Date as varchar(40)) + '=' + cast(audit.DeploymentDate as varchar(40), 
  log.Address + '=' + audit.ShippingAddress,
  log.Products+ '=' + audit.Options
  --etc
from Audit audit, Log log
  where audit.CardID=log.RecordId

会输出类似的内容:

  

1 = 1 Test = TestName 11/09/2009 = 2009年11月10日null =我的地址null =车轮

这有效,但构建非常烦人。我想到的另一件事是对列进行别名,将两个表联合起来,然后对它们进行排序,使它们以列表形式存在。这样我就可以看到列比较了。这带来了所有联盟的明显开销。

即:

  

Log 1 Test 11/09/2009 null,null
  审计1 TestName 11/10/2009我的地址车轮

有关更好地审核此数据的方法的任何建议吗?

让我知道您可能还有其他问题。

补充说明。我们想要减少不重要的信息,所以在某些情况下,如果列相等,我们可能会使列无效(但我知道它太慢了)

  case when log.[Name]<>audit.[CarName] then (log.[Name] + '!=' + audit.[CarName]) else null end

或者如果我们正在采取第二种方式

  nullif(log.[Name], audit.[CarName]) as [Name]
  ,nullif(audit.[CarName], log.[Name]) as [Name]

2 个答案:

答案 0 :(得分:2)

我发现杰夫史密斯给出here的例程有助于过去进行表格比较。这至少可以为您提供良好的入门基础。该链接上提供的代码是:

CREATE PROCEDURE CompareTables(@table1 varchar(100), 
    @table2 Varchar(100), @T1ColumnList varchar(1000),
    @T2ColumnList varchar(1000) = '')
AS

-- Table1, Table2 are the tables or views to compare.
-- T1ColumnList is the list of columns to compare, from table1.
-- Just list them comma-separated, like in a GROUP BY clause.
-- If T2ColumnList is not specified, it is assumed to be the same
-- as T1ColumnList.  Otherwise, list the columns of Table2 in
-- the same order as the columns in table1 that you wish to compare.
--
-- The result is all records from either table that do NOT match
-- the other table, along with which table the record is from.

declare @SQL varchar(8000);

IF @t2ColumnList = '' SET @T2ColumnList = @T1ColumnList

set @SQL = 'SELECT ''' + @table1 + ''' AS TableName, ' + @t1ColumnList +
 ' FROM ' + @Table1 + ' UNION ALL SELECT ''' + @table2 + ''' As TableName, ' +
 @t2ColumnList + ' FROM ' + @Table2

set @SQL = 'SELECT Max(TableName) as TableName, ' + @t1ColumnList +
 ' FROM (' + @SQL + ') A GROUP BY ' + @t1ColumnList + 
 ' HAVING COUNT(*) = 1'

exec ( @SQL)

答案 1 :(得分:0)

这样的事情对你有用:

select 
  (Case when log.RecordID = audit.CardID THEN 1 else 0) as RecordIdEqual,
  (Case when log.Name = audit.Name THEN 1 else 0) as NamesEqual ,
  (Case when log.Date = audit.DeploymentDate THEN 1 else 0) as DatesEqual, 
  (Case when log.Address = audit.ShippingAddress THEN 1 else 0) as AddressEqual,
  (Case when log.Products = audit.Options THEN 1 else 0) as ProductsEqual
  --etc
from Audit audit, Log log
  where audit.CardID=log.RecordId

这将根据列名称分解相同的内容。看起来它可能比完成所有的转换更容易,并且必须解释生成的字符串...