mssqltips logo

Ways to compare and find differences for SQL Server tables and data

By:   |   Updated: 2019-05-22   |   Comments (23)   |   Related: 1 | 2 | 3 | 4 | More > Comparison Data and Objects

Problem

Sometimes we need to compare SQL Server tables and/or data to know what was changed. This tip shows you different ways to compare data, datatypes and tables using SQL Server.

Solution

I will show you different methods to identify changes. Let's say that we have two similar tables in different databases and we want to know what is different.

Here is a script that creates sample databases, tables and data.

CREATE DATABASE dbtest01
GO
USE dbtest01
GO

CREATE TABLE [dbo].[article] ([id] [nchar](10) NOT NULL, [type] [nchar](10) NULL, [cost] [nchar](10) NULL,
  CONSTRAINT [PK_article] PRIMARY KEY CLUSTERED
  (
  [id] ASC
  ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO [dbo].[article]
  VALUES ('001', '1', '40'),
  ('002', '2', '80'),
  ('003', '3', '120')
GO

CREATE DATABASE dbtest02
GO
USE dbtest02
GO

CREATE TABLE [dbo].[article] ([id] [nchar](10) NOT NULL, [type] [nchar](10) NULL, [cost] [nchar](10) NULL,
  CONSTRAINT [PK_article] PRIMARY KEY CLUSTERED
  (
  [id] ASC
  ) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

INSERT INTO [dbo].[article]
  VALUES ('001', '1', '40'),
  ('002', '2', '80'),
  ('003', '3', '120'),
  ('004', '4', '160')
GO

The T-SQL code generates 2 tables in different databases. The table names are the same, but the table in database dbtest02 contains an extra row as shown below:

The tables

Let's look at ways we can compare these tables using different methods.

Compare SQL Server Data in Tables Using a LEFT JOIN

With the LEFT JOIN we can compare values of specific columns that are not common between two tables.

For example:

SELECT *
FROM      dbtest02.dbo.article d2
LEFT JOIN dbtest01.dbo.article d1 ON d2.id = d1.id  

The left join shows all rows from the left table "dbtest02.dbo.article", even if there are no matches in table "dbtest01.dbo.article":

Left join

In this example, we are comparing 2 tables and the values of NULL are displayed if there are no matching rows. This method works to verify new rows, but if we update other columns, the LEFT JOIN does not help.

This can be done both ways to see if there are differences the other way around. This query will just return the 3 matching rows.

SELECT *
FROM      dbtest01.dbo.article d1
LEFT JOIN dbtest02.dbo.article d2 ON d1.id = d2.id

Compare SQL Server Data in Tables Using the EXCEPT Clause

Except shows the difference between two tables (the Oracle guys use minus instead of except and the syntax and use is the same). It is used to compare the differences between two tables. For example, let's see the differences between the two tables:

Now let's run a query using except:

SELECT * FROM dbtest02.dbo.article
EXCEPT
SELECT * FROM dbtest01.dbo.article

The except returns the difference between the tables from dbtest02 and dbtest01:

Except

If we flip the tables around in the query we won't see any records, because the table in database dbtest02 has all of the records plus one extra.

SELECT * FROM dbtest01.dbo.article
EXCEPT
SELECT * FROM dbtest02.dbo.article

This method is better than the first one, because if we change values for other columns like the type and cost, EXCEPT will notice the difference.

Here is an example if we update id "001" in database dbtest01 and change the cost from "40" to "1".  If we update the records and then run the query again we will see these differences now:

except clause differences

Unfortunately it does not create a script to synchronize the tables.

Compare SQL Server Data in Tables Using the Tablediff Tool

There is a nice command line tool used to compare tables.  This can be found in "C:\Program Files\Microsoft SQL Server\110\COM\" folder. This command line tool is used to compare tables. It also generates a script with the INSERT, UPDATE and DELETE statements to synchronize the tables. For more details, refer to this tablediff article.

Compare SQL Server Data in Tables Using Change Data Capture (CDC)

This feature is available in SQL Server 2008 and later. You need to enable this feature and you also need to have SQL Server Agent running. Basically it creates system tables that track the changes in your tables that you want to monitor. It does not compare tables, but it tracks the changes in tables.

For more information, refer to these Change Data Capture (CDC) tips.

Compare SQL Server Data Types Between Two Tables

What happen if we want to compare the data types? Is there a way to compare the datatypes?

Yes, we can use the [INFORMATION_SCHEMA].[COLUMNS] system views to verify and compare the information. We are going to create a new table named dbo.article2 with a column with different data type than the dbo.article table:

USE dbtest01
GO

CREATE TABLE [dbo].[article2](
 [id] [int] NOT NULL,
 [type] nchar(10) NULL,
 [cost] nchar(10) NULL,
 CONSTRAINT [PK_article1] PRIMARY KEY CLUSTERED 
(
 [id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

The difference is that the id is now an int instead of nchar(10) like the other tables.

The query to compare data types of tables article and article1 would be:

USE dbtest01
GO

SELECT
  c1.table_name,
  c1.COLUMN_NAME,
  c1.DATA_TYPE,
  c2.table_name,
  c2.DATA_TYPE,
  c2.COLUMN_NAME
FROM      [INFORMATION_SCHEMA].[COLUMNS] c1
LEFT JOIN [INFORMATION_SCHEMA].[COLUMNS] c2 ON c1.COLUMN_NAME = c2.COLUMN_NAME
WHERE c1.TABLE_NAME = 'article'
  AND c2.TABLE_NAME = 'article2'
  AND c1.data_type <> c2.DATA_TYPE

The results are as follows:

Except

The query compares the data types from these two tables. All the information of the columns can be obtained from the [INFORMATION_SCHEMA].[COLUMNS] system view. We are comparing the table "article" with table "article2" and showing if any of the datatypes are different.

Compare if there are Extra Columns Between SQL Server Tables

Sometimes we need to make sure that two tables contain the same number of columns. To illustrate this we are going to create a table named "article3" with 2 extra columns named extra1 and extra2:

USE dbtest01
GO

CREATE TABLE [dbo].[article3](
 [id] [int] NOT NULL,
 [type] nchar(10) NULL,
 [cost] nchar(10) NULL,
 extra1 int,
 extra2 int
)

In order to compare the columns I will use this query:

USE dbtest01
GO

SELECT
  c2.table_name,
  c2.COLUMN_NAME
FROM [INFORMATION_SCHEMA].[COLUMNS] c2
WHERE table_name = 'article3'
  AND c2.COLUMN_NAME NOT IN 
     ( SELECT column_name
       FROM [INFORMATION_SCHEMA].[COLUMNS]
       WHERE table_name = 'article'
     )

The query compares the different columns between table "article" and "article3". The different columns are extra1 and extra2. This is the result of the query:

compare extra columns

Compare SQL Server Tables in Different Databases

Now let's compare the tables in database dbtest01 and dbtest02. The following query will show the different tables in dbtest01 compared with dbtest02:

SELECT 'dbtest01' AS dbname, t1.table_name
FROM dbtest01.[INFORMATION_SCHEMA].[tables] t1
WHERE table_name NOT IN 
     ( SELECT t2.table_name
       FROM dbtest02.[INFORMATION_SCHEMA].[tables] t2
     )
UNION
SELECT 'dbtest02' AS dbname, t1.table_name
FROM dbtest02.[INFORMATION_SCHEMA].[tables] t1
WHERE table_name NOT IN 
     ( SELECT t2.table_name
       FROM dbtest01.[INFORMATION_SCHEMA].[tables] t2
     )
compare tables between databases

Third Party Tools

There are great tools to compare tables including data and schemas. You can use Visual Studio or use other SQL Server Comparison tools.

Next Steps


Last Updated: 2019-05-22


get scripts

next tip button



About the author




Post a comment or let the author know this tip helped.

All comments are reviewed, so stay on subject or we may delete your comment. Note: your email address is not published. Required fields are marked with an asterisk (*).

*Name
*Email
Email me updates

Signup for our newsletter

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.





Monday, May 13, 2019 - 8:52:21 AM - db042188 Back To Top

 pls use caution with the except statement.  it drops duplicates automatically from the left and right.  in biz intelligence that isnt acceptable as the dupes are either necessary or an error that needs to be caught.


Friday, May 10, 2019 - 1:23:28 AM - testMail Back To Top

I have done this using powershell and you can also use this :

$ss = "souce_server" ;
$sd = "source_database" ;
$st = "source_table" ;

$ds = "destination_server" ;
$dd = "destination_database" ;
$dt = "destination_table" ;

$tablediff_directory = "C:\Program Files\Microsoft SQL Server\130\COM\" ;
$op = "D:\test.sql" ;

CD $tablediff_directory

tablediff.exe -f $op -sourceserver $ss -sourcedatabase $sd -sourcetable $st -destinationserver $ds -destinationdatabase $dd -destinationtable $dt

Wednesday, February 14, 2018 - 6:17:35 AM - Ranjan Back To Top

 

Thanks Daniel for this article. I have a requirement to find the difference between two tables of same data but the primary keys will be different, so I have a difficulty in identifying which all records are inserted in the source records and which all records are updated in the source table. Could you please help me?

I tried MERGE and EXCEPT, but not much luck.

 

Thanks,

Ranjan


Wednesday, September 20, 2017 - 3:18:04 AM - Muhammad Waseem Back To Top

Dear Daniel

Its amazing article you wrote. I am sure it will help others  as well ,  Welldone !!!!!

 

 


Tuesday, October 18, 2016 - 3:52:16 PM - Manjinder Back To Top

Thank you very much Daniel! Well written & easy to understand and follow plus thorough as most articles are on this site. Keep up the excellent work of sharing the knowledge! :-) 

 


Wednesday, February 17, 2016 - 12:54:47 PM - Barry Seymour Back To Top

THANK YOU THANK YOU THANK YOU! I never knew of the EXCEPT keyword. It makes a ton of my earlier attempts at table comparison moot, but I don't care! An excellent summation.

 


Wednesday, January 28, 2015 - 2:28:03 AM - PRADEEP KUMBHAR Back To Top

when i run query in sql server 2012 it join 2 tables but all field contain same data display.

Please get the solution .


Tuesday, July 29, 2014 - 10:38:59 AM - Greg Robidoux Back To Top

Hi Jayesh, this can be done but it takes a lot of coding to figure out which rows are different and then which columns are different.  You could use the EXCEPT method shown above to show records that are different, but then you will need to take the results from that and write a process to compare column by column.  I don't think we have a tip that does this, so maybe someone could write a tip.


Tuesday, July 29, 2014 - 8:05:10 AM - Jayesh Back To Top

 

Helllo please read this instead of above,

i want to compare two tables from different database, suppose

both tables have 5 raw

in which

table 1 and table 2 has 4 raw exactly same,

but fifth raw has minor change in one column value

 

if i want to to see only that value not entire raw then

what to do?

 

red gate can't give specic difffrent column value


Thursday, July 10, 2014 - 4:45:38 AM - Nitin Sharma Back To Top

why do we use procedure


Tuesday, June 10, 2014 - 6:46:58 PM - Arun kumar (SQL Developer) Back To Top

I liked this post, but this will not full fill for the dependent table. I have faced an issue when accidently 1 master table updated in source table that has updated multiple table on multiple server, in some table it uses foreign key relation ship. Now we have to identify all the changes related to this one. This changes also replicated to diffrent server. We were thinking can we do with this approach but did not found solution on the spot. We have worked 1 by one table then we sync the table.

If you developer think it can also generate script for dependent table please share. Thanks a lot !!!!

 

 


Wednesday, November 06, 2013 - 5:06:40 PM - Salvador Nava Back To Top

Thanks a lot!!! Very useful!!!


Thursday, August 29, 2013 - 2:50:55 AM - Geoffrey Back To Top

I recomment SQL Negotiator Pro from Aphilen software www.aphilen.com they offer a free version which may suffice your needs

The full blown version comes with the ability to

Compare unlimited databases, generate management reports, graphically display database dependencies, SQL server monitor etc etc


Thursday, May 23, 2013 - 6:13:57 AM - SergeiK Back To Top

Why not just use Red Gate's SQL Data Compare tool (http://www.red-gate.com/products/sql-development/sql-data-compare/)?

Answer: May be because Red Gate's Tool costs about 500 $ ?

I choosed Devart's products for my needs which are much cheaper and the same proffesional.

For this need you can use SQL Data Compare from Devart (http://www.devart.com/dbforge/sql/datacompare/)


Tuesday, March 26, 2013 - 7:35:23 AM - Satish Back To Top

Thank you Daniel for your good article. 


Sunday, March 17, 2013 - 3:54:11 PM - Ari Mäenpää Back To Top

Excellent page, I have found this already twice when needed this! Maybe I should now bookmark this.

Thank you!


Tuesday, October 23, 2012 - 11:27:52 AM - Boris Tyukin Back To Top

@David McKinney

sorry, looks his site is down...but when I tested this query below, it was the fastest:

 

SELECT MIN(id) AS id, col1, col2, col3 FROM (SELECT id, col1, col2, col3 FROM tbl1 UNION ALL SELECT id, col1, col2, col3 FROM tbl2) X GROUP BY col1, col2, col3 HAVING COUNT(1)=1

It also works well with NULLs. He does Union ALL, but HAVING COUNT(1)=1 will output only records not found in one of the tables, so matches will be suppressed


Tuesday, October 23, 2012 - 10:58:06 AM - David McKinney Back To Top

@Boris I couldn't get your link to work (for Lee Everest's article).

I have a method using UNION as well but not UNION ALL

It relies on the fact that

select 'alpha' UNION select 'alpha' will only return 1 row (and not 2).  Hence if you UNION 2 tables with 1000 rows each together, if they're identical, the result will have 1000 rows also.  You can then look for duplicates on the PKey field(s) to identify those rows which are different.


Tuesday, October 23, 2012 - 9:04:26 AM - Daniel Calbimonte Back To Top

Yes,

There is already a pretty nice article related to third party tools to compare data

http://www.mssqltips.com/products.asp?catid=25

Personally I love SQL Data Compare from Redgate and SQL Data Compare from devart.

My original article included some demos about 3 third party tools, but the editors decided not to promote third party tools.


Monday, October 22, 2012 - 3:56:53 PM - John Fox Back To Top
A simple method that I use that works quite well and is free is to create a SQL query that looks like the following. If one is familiar with tools that use regular expressions, it can be done quite quickly by starting with the output of 'script table as select' using SMS. Assuming the keys are the primary keys, it is only necessary to check one of them for each table to null to detect a 'missing row' condition. And it is amazing what data types compare quite well using '-1' as the default if null. Of course, one has to be smart and if '-1' is a valid data condition then either some other value of checking specifically for 'is null' should be used. After running the SQL, I usually load it into excel, cut all of the data from 'Test' to the last column and last row, then paste it after the 'prod' data. A quick sort by key1/key2 then makes it pretty easy to walk through the data.


select 'Prod',t1.key1, t1.key2, t1.field3, t1.fiel4, 'Test',t2.key1, t2.key2, t2.field3, t2.fiel4
from ProductionTable t1
full join TestingTable t2 on t1.key1 = t2.key1 and t2.key2 = t2.key2
where t1.key1 is null
or t2.key1 is null
or isnull(t1.field3,-1) != isnull(t2.field3,-1)
or isnull(t1.field4,-1) != isnull(t2.field4,-1)

Monday, October 22, 2012 - 2:02:42 PM - TimothyAWiseman Back To Top

Great article, thank you for providing it.

 

I somewhat agree wtih Marting Borgars.  I am a big fan of Red Gate's SQL Data Compare and Red Gate's SQL Compare when looking at schemas, I have been extremely happy with them.  

But there are times when those won't be available.  As Boris points out, they aren't free (well worth the price though), so you may not always have them, especially when working for a small client on a small project.  Some institutions also have very lengthy validation procedures for installing software due to security concerns. 

It is also good to be able to do it "by hand" just for the sake of having a thorough knowledge base and understanding of how things work, even if you will use the tools most of the time. 


Monday, October 22, 2012 - 10:14:23 AM - Boris Tyukin Back To Top

Thanks for the interesting article!

Red Gate's SQL Data Compare tool is nice indeed and we use it at work but it is not free so it is great to see alternatives.

Some time ago I bookmarked very fast and cool method, described by Lee Everest here

The idea is to use query like that:

SELECT MIN(id) AS id, col1, col2, col3 FROM (SELECT id, col1, col2, col3 FROM tbl1 UNION ALL SELECT id, col1, col2, col3 FROM tbl2) X GROUP BY col1, col2, col3 HAVING COUNT(1)=1

 

 

 


Monday, October 22, 2012 - 8:23:56 AM - Martin Borgars Back To Top

Why not just use Red Gate's SQL Data Compare tool (http://www.red-gate.com/products/sql-development/sql-data-compare/)?



download

























get free sql tips

I agree by submitting my data to receive communications, account updates and/or special offers about SQL Server from MSSQLTips and/or its Sponsors. I have read the privacy statement and understand I may unsubscribe at any time.



Learn more about SQL Server tools