Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing two T-SQL tables for diffs

I have two instances of the same database. The first db represents data from today, the second data from 6 months ago. I need to find differences for a subset of entries in a specific table.

For entries with ids that are in both tables, I'd like to find a way to view only the rows that aren't identical.

Any ideas?

Thanks

like image 695
srmark Avatar asked Sep 24 '09 17:09

srmark


People also ask

How can I compare two tables for differences in SQL?

Compare Tables Data Using a LEFT JOIN The LEFT JOIN T-SQL keyword is used to retrieve data from two tables, by returning all records from the left table and only the matched records from the right table and NULL values from the right table when there is no matching between the two tables.

How do I compare two tables in SQL to find unmatched records?

Use the Find Unmatched Query Wizard to compare two tables One the Create tab, in the Queries group, click Query Wizard. In the New Query dialog box, double-click Find Unmatched Query Wizard. On the first page of the wizard, select the table that has unmatched records, and then click Next.

How do you compare two similar tables?

Compare two tables by using joins. To compare two tables by using joins, you create a select query that includes both tables. If there is not already an existing relationship between the tables on the fields that contain the corresponding data, you create a join on the fields that you want to examine for matches.


2 Answers

SELECT t1.id
FROM table1 t1
INNER JOIN table2 t2 ON t1.id = t2.id
WHERE ISNULL(t1.field1,'') <> ISNULL(t2.field1,'')
      OR ISNULL(t1.field2,'') <> ISNULL(t2.field2,'')
      OR ...

To produce long WHERE part you can use this function:

CREATE PROCEDURE compareTables
    @db1    NVARCHAR(100),
    @table1 NVARCHAR(100),
    @db2    NVARCHAR(100),
    @table2 NVARCHAR(100)
AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @where NVARCHAR(MAX)
    DECLARE @cmd NVARCHAR(MAX)

    SET @where = ''

    SELECT @where = @where + 'ISNULL(t1.' + name + ','''') <> ISNULL(t2.' + name + ','''') OR ' 
    FROM sys.columns WHERE object_id = OBJECT_ID(@table1)

    SET @where = SUBSTRING(@where,1,LEN(@where)-3)

    SET @cmd = 'SELECT t1.id FROM ' + @db1 + '.' + @table1 + ' t1 '
    SET @cmd = @cmd + 'INNER JOIN ' + @db2 + '.' + @table2 + ' t2 ON t1.id = t2.id '
    SET @cmd = @cmd + 'WHERE ' + @where

    EXEC sp_executesql @cmd
END
GO

Example usage:

EXEC compareTables 'db1_name','dbo.table1','db2_name','dbo.table1'

Remember to put schema in the table name.

like image 157
Lukasz Lysik Avatar answered Oct 07 '22 19:10

Lukasz Lysik


From your text, I think you say there is an ID that can be used for matching rows.

SELECT t1.*, t2.*
FROM table1 t1 JOIN table2 t2 ON t1.id=t2.id 
WHERE BINARY_CHECKSUM(t1.*) <> BINARY_CHECKSUM(t2.*)

Untested, but should work.

like image 25
Jonas Lincoln Avatar answered Oct 07 '22 20:10

Jonas Lincoln