简体   繁体   中英

Merge tables where NULL

I have two tables like this

Table 1

+-----------+----------+-------+-------------------+
| AGENCY_ID | LOCAL_ID | CLASS |      LRS_ID       |
+-----------+----------+-------+-------------------+
|       651 | 1        | NULL  | 10200000690000001 |
|       651 | 2        | NULL  | 10200000690205B01 |
|       651 | 3        | NULL  | 10200000690293C01 |
|       651 | 4        | NULL  | 10200000690293D01 |
+-----------+----------+-------+-------------------+

Table 2

+-----------+----------+-------+-------------------+
| AGENCY_ID | LOCAL_ID | CLASS |      LRS_ID       |
+-----------+----------+-------+-------------------+
|       651 | NULL     | 1     | 10200000690000001 |
|       651 | NULL     | NULL  | 10200000690000091 |
|       651 | NULL     | 7     | 10200000690205B01 |
|       651 | NULL     | 1     | 10200000690293C01 |
+-----------+----------+-------+-------------------+

And I want the result to be

+-----------+----------+-------+-------------------+
| AGENCY_ID | LOCAL_ID | CLASS |      LRS_ID       |
+-----------+----------+-------+-------------------+
|       651 | 1        | 1     | 10200000690000001 |
|       651 | 2        | 7     | 10200000690205B01 |
|       651 | 3        | 1     | 10200000690293C01 |
|       651 | 4        | NULL  | 10200000690293D01 |
+-----------+----------+-------+-------------------+

Taking table 2 and merging the non-NULL values to table 1. Here I only specify the CLASS field but there are 50+ fields that are always NULL in Table 1 and may or may not be NULL in table 2. So just specifying manually which fields I want is the problem, I want it to automatically replace it if its NULL and table 2 has it.

Key things to note is that LRS_ID is the JOIN key. LRS_ID that exist in table 2 and not table 1 don't exist in the output. LRS_ID that exists in table 1 but not table 2 remain but CLASS remains NULL.

You could use left join to get your expected output like this:

select
    t1.AGENCY_ID,
    ISNULL(t1.LOCAL_ID,t2.LOCAL_ID)LOCAL_ID,
    ISNULL(t1.CLASS,t2.CLASS)CLASS,
    t1.LRS_ID
from table1 t1 
left join table2 t2 on
    t1.LRS_ID = t2.LRS_ID

SQL Fiddle Demo

Just join the tables and find the first value you want. Select:

select
    t1.AGENCY_ID,
    ISNULL(t1.LOCAL_ID,t2.LOCAL_ID)LOCAL_ID,
    ISNULL(t1.CLASS,t2.CLASS)CLASS,
    t1.LRS_ID
from table1 t1 
inner join table2 t2 on
    t1.LRS_ID = t2.LRS_ID

Reverse ISNULL to give priority to t2.

To update:

update t
    LOCAL_ID = ISNULL(t.LOCAL_ID,t2.LOCAL_ID),
    CLASS = ISNULL(t.CLASS,t2.CLASS)
from table1 t
inner join table2 t2 on
    t1.LRS_ID = t2.LRS_ID

First you get a distinct list of all the LRS_ID's from both tables, as some may exist in one table but not the other. Then, outer join to both tables based on the LRS_ID. Finally, use COALESCE to get the first non-null value from either table for each field.

SELECT
    DerivedAllLRS_IDs.LRS_ID,
    COALESCE([Table 1].AGENCY_ID, [Table 2].AGENCY_ID) AS AGENCY_ID,
    COALESCE([Table 1].LOCAL_ID, [Table 2].LOCAL_ID) AS LOCAL_ID,
    COALESCE([Table 1].CLASS, [Table 2].CLASS) AS CLASS
FROM
    (
    SELECT DISTINCT 
        LRS_ID
    FROM
        (
        (SELECT LRS_ID FROM [Table 1])
        UNION ALL
        (SELECT LRS_ID FROM [Table 2])
        )DerivedUnion
    ) DerivedAllLRS_IDs
    LEFT OUTER JOIN [Table 1] ON DerivedAllLRS_IDs.LRS_ID = [Table 1].LRS_ID
    LEFT OUTER JOIN [Table 2] ON DerivedAllLRS_IDs.LRS_ID = [Table 2].LRS_ID

Note that if you are looking to modify the underlying data, it will require two passes. First, an UPDATE statement on existing records in [Table 1] to plug the missing info that exists in [Table 2] , then a set of INSERT statements to get data for rows where the LRS_ID only exists in [Table 2] into [Table 1] .

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