简体   繁体   中英

Output unmatched columns when comparing two sql tables

I need to build a query where I can output only the columns which do not match in two tables A and B (same structure)

For example table A and B both have 10 columns with same 3 primary keys. (Reason for doing this is to find data entry errors in either table A or B)

For example table A has the values: ABC 1 2 3 4 5 6 7 (this is one row, ABC are the values for primary keys) Table B has the values ABC 1 2 3 4 5 6 8 (this is one row, ABC are the values for primary keys)

As you can see the 10th column has different values (7 in table A, 8 in table B). The result of the query should be Columns 1,2,3 & 10, along with the values in table B.

It is actually very simple to return the rows that differ:

select t1.A, t1.B, t1.C
from table1 t1
inner join table2 t2 on t1.A = t2.A and t1.B = t2.B and t1.C = t2.C
where t1.C1 != t2.C1 or t1.C2 != t2.C2 -- and so on for the remaining columns

This will return the primary key of the rows that are different. If you really need to name of the column they are different at, it will become much more complex as you need to return the same number of columns for each row. You can't have a dynamic number of columns.

You could create a union query such as:

SELECT Table2.Key1, Table2.Key2, Table2.Key3, CASE WHEN Table1.Value1 <> Table2.Value1 THEN 'Value1' END AS DifferingFields
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value1 <> Table2.Value1
    UNION ALL
    SELECT Table2.Key1, Table2.Key2, Table2.Key3, CASE WHEN Table1.Value2 <> Table2.Value2 THEN 'Value2' END
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value2 <> Table2.Value2
    UNION ALL
    SELECT Table2.Key1, Table2.Key2, Table2.Key3, CASE WHEN Table1.Value3 <> Table2.Value3 THEN 'Value3' END
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value3 <> Table2.Value3
    [... add statements for the remaining value fields ...]

This will return the values of the 3 key fields, with the names of the fields that are contain differing values.

For Microsoft Access, use:

SELECT Table2.Key1, Table2.Key2, Table2.Key3, IIF(Table1.Value1 <> Table2.Value1,"Value1","") AS DifferingFields
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value1 <> Table2.Value1
    UNION ALL
    SELECT Table2.Key1, Table2.Key2, Table2.Key3, IIF(Table1.Value2 <> Table2.Value2, "Value2","")
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value2 <> Table2.Value2
    UNION ALL
    SELECT Table2.Key1, Table2.Key2, Table2.Key3, IIF(Table1.Value3 <> Table2.Value3, "Value3","")
    FROM Table2 LEFT JOIN Table1 ON Table2.Key1 = Table1.Key1 AND Table2.Key2 = Table1.Key2 AND Table2.Key3 = Table1.Key3
    WHERE Table1.Value3 <> Table2.Value3

If you consider the following data:

Table1:
Key1 Key2 Key3 Value1 Value2 Value3
1 2 3 4 5 6
1 2 4 4 5 8
1 2 5 4 5 10
1 2 6 4 6 10

Table2:
Key1 Key2 Key3 Value1 Value2 Value3
1 2 3 4 5 7
1 2 4 4 5 9
1 2 5 4 5 11
1 2 6 4 5 11

You get results as:
Key1 Key2 Key3 DifferingFields
1 2 6 Value2
1 2 3 Value3
1 2 4 Value3
1 2 5 Value3
1 2 6 Value3

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM