views:

1148

answers:

5

I am trying to compare two tables, SQL Server, to verify some data. I want to return all the rows from both tables where data is either in one or the other. In essence, I want to show all the discrepancies. I need to check three pieces of data in doing so, FirstName, LastName and Product.

I'm fairly new to SQL and it seems like a lot of the solutions I'm finding are over complicating things. I don't have to worry about NULLs.

I started by trying something like this:

SELECT DISTINCT [First Name], [Last Name], [Product Name] FROM [Temp Test Data]
WHERE ([First Name] NOT IN (SELECT [First Name] 
FROM [Real Data]))

I'm having trouble taking this further though.

Thanks!

EDIT:

Based on the answer by @treaschf I have been trying to use a variation of the following query:

SELECT td.[First Name], td.[Last Name], td.[Product Name]
FROM [Temp Test Data] td FULL OUTER JOIN [Data] AS d 
ON td.[First Name] = d.[First Name] AND td.[Last Name] = d.[Last Name] 
WHERE (d.[First Name] = NULL) AND (d.[Last Name] = NULL)

But I keep getting 0 results back, when I know that there is at least 1 row in td that is not in d.

EDIT:

Ok, I think I figured it out. At least in my few minutes of testing it seems to work good enough.

SELECT [First Name], [Last Name]
FROM [Temp Test Data] AS td
WHERE (NOT EXISTS
        (SELECT [First Name], [Last Name]
         FROM [Data] AS d
         WHERE ([First Name] = td.[First Name]) OR ([Last Name] = td.[Last Name])))

This is basically going to tell me what is in my test data that is not in my real data. Which is completely fine for what I need to do.

+1  A: 

Let someone else do all the heavy lifting for you. This is not trivial to do. Take a look at Red-Gate's Data Compare product.

Randy Minder
If I had the extra $$$ to throw around maybe. At the moment not possible to go with a pay product.
Casey
It is trivial for SQL Server 2005+, actually. See erikkallen's answer.
RedFilter
+1  A: 

IF you have tables A and B, both with colum C, here are the records, which are present in table A but not in B:

SELECT A.*
FROM A
    LEFT JOIN B ON (A.C = B.C)
WHERE B.C IS NULL

To get all the differences with a single query, a full join must be used, like this:

SELECT A.*, B.*
FROM A
    FULL JOIN B ON (A.C = B.C)
WHERE A.C IS NULL OR B.C IS NULL

What you need to know in this case is, that when a record can be found in A, but not in B, than the columns which come from B will be NULL, and similarly for those, which are present in B and not in A, the columns from A will be null.

treaschf
I'm having trouble getting this working right, see my recent edit up top.
Casey
The problem might be that you cannot compare a value with null using '='. (Or at least when SET ANSI_NULLS is ON.) You must say: value IS NULL or value IS NOT NULL.
treaschf
I'm marking this as the answer I used because in doing this way I was able to easily do a few other things I had to later on.
Casey
+3  A: 
SELECT * FROM (SELECT * FROM table1
               EXCEPT
               SELECT * FROM table2) a
UNION ALL
SELECT * FROM (SELECT * FROM table2
               EXCEPT
               SELECT * FROM table1) b
erikkallen
+1: This is the sensible way for SQL Server 2005+.
RedFilter
*(Added missing aliases for subqueries.)*
RedFilter
A: 

Try this :

SELECT 
    [First Name], [Last Name]
FROM 
    [Temp Test Data] AS td EXCEPTION JOIN [Data] AS d ON 
         (d.[First Name] = td.[First Name] OR d.[Last Name] = td.[Last Name])

Much simpler to read.

Kango_V
A: 

Hi there,

You might want to give a try to Volpet's Table Diff:

http://www.volpet.com/

You can try a fully-functional copy for 30 days.

Gia