2010-09-13 4 views
1

Concept simple nous faisons fondamentalement un peu d'audit, en comparant ce qui est entré, et ce qui s'est réellement passé pendant le traitement. Je suis à la recherche d'une meilleure façon d'exécuter une requête qui peut faire des comparaisons côte à côte avec des colonnes qui diffèrent légèrement dans le nom et le type de potentiy.SQL Server Comparer des tableaux similaires avec la requête

DB Mise en page:

Table (* est la condition de jointure)

Log (enregistrement de données non modifié.TotalMix.)
- LogID
- RecordID *
- Nom
- Date
- Adresse
- Produits
- etc.

Audit (record post-traitement)
- CARDID *
- RARnom
- DeploymentDate
- ShippingAddress
- Options
- etc.

Pour par exemple ce serait de travail si vous regardez après le comp ennuyeux lexité à écrire, et les problèmes de performance.

La requête se joint à gauche et à droite et les sélectionne comme des chaînes. Affichage de chaque champ correspondant.

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 

Ce qui serait quelque chose comme de sortie:

1 = 1 test = TestName 11/09/2009 = 11/10/2009 null = Mon adresse null = Roues

Cette fonctionne mais est extrêmement ennuyeux à construire. Une autre chose à laquelle je pensais était de simplement alias les colonnes, d'unir les deux tables, et de les ordonner pour qu'elles soient sous forme de liste. Cela me permettrait de voir les comparaisons de colonnes. Cela vient avec les frais généraux évidents de l'union tous.

-à-dire:

Log 1 test 11/09/2009 null, null
Audit 1 TestName 11/10/2009 Mon adresse Roues

Toutes les suggestions sur une meilleure façon de vérifier ces données? Dites-moi quelles autres questions vous pourriez avoir.

Remarques supplémentaires.Nous allons vouloir réduire l'information sans importance si, dans certains cas, nous pourrions Null la colonne si elles sont égales (mais je sais que trop lent)

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

ou si nous faisons la deuxième façon

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

Que voulez-vous dire par un meilleur moyen? Cherchez-vous un meilleur moyen d'afficher les données afin de pouvoir les lire plus clairement? Voulez-vous limiter les données uniquement aux personnes ayant des différences? –

+0

Mieux que dans la performance, et la lisibilité. Nous faisons beaucoup de travail pour analyser ces données, donc nous filtrerons au besoin, mais nous pourrions aussi faire quelque chose comme ce qui précède. Si certaines colonnes sont égales, nous pourrions les annuler afin que nous puissions passer plus rapidement au crible les résultats. – Nix

+0

Qu'essayez-vous d'accomplir? Plus d'infos, s'il vous plait. –

Répondre

2

J'ai trouvé la routine donnée par Jeff Smith pour être utile pour faire des comparaisons de tables dans le passé. Cela pourrait au moins vous donner une bonne base de départ. Le code donné sur ce lien est:

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) 
0

Would quelque chose comme ce travail pour vous:

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 

cela vous donnera une ventilation de ce qui est égale en fonction du nom de la colonne. On dirait que cela pourrait être plus facile que de faire tout le casting et d'avoir à interpréter la chaîne résultante ...

+0

Je fais le casting parce que si les enregistrements sont égaux nous pourrions avoir besoin de connaître la valeur de la colonne. Supposons que la colonne A est correcte (et est l'identifiant unique) et B est incorrect, nous aurions besoin de voir la valeur de A. Mais je vais probablement utiliser cette stratégie pour filtrer les valeurs qui ne sont pas aussi importantes. – Nix

Questions connexes