简体   繁体   中英

Compare two tables and insert all records with added or removed status in 3rd table using SQL Server procedure

I have table A and table B . I have to compare this tables records and insert data to table C using SQL Server procedure in below format

table A

  name
  A
  B
  C
  D
  E
  F
  G

table B

  name
  A
  B
  Q
  C
  D
  F
  G

table c should be like below. it has an extra field 'status' to mention record is added or removed.

name   status
A  
B
Q      newly added
C
D      
E      removed
F
G

I know we can compare 2 tables and find added or removed records using EXCEPT and UNION operations. But in this case, I have to integrate that records with unchanged records and should place that added or removed records in correct position.

You can do this with a full join and conditional logic:

select 
    coalesce(a.name, b.name) name,
    case
        when a.name is null then 'newly added'
        when b.name is null then 'removed'
    end status
from tablea a
full join tableb b on b.name = a.name
order by name

Demo on DB Fiddle :

name | status     
:--- | :----------
A    | null       
B    | null       
C    | null       
D    | null       
E    | removed    
F    | null       
G    | null       
Q    | newly added

Depending on which order do you want to accomplish at the end you can use this:

select name, max(status), descr from(
select 
    coalesce(a.col, b.col) name,
    coalesce(a.descr, b.descr) descr,
    case
        when a.col is null then 'newly added'
        when b.col is null then 'removed'
    end status
    , ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) rn
from a a
left join b b on b.col = a.col
union
select 
    coalesce(a.col, b.col) name,
    coalesce(a.descr, b.descr) descr,
    case
        when a.col is null then 'newly added'
        when b.col is null then 'removed'
    end status
    , ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) rn
from b b
left join a a on b.col = a.col) A
group by name, descr
order by max(rn);

And then if you want to order by how it is in table a then in first select select from b left join a and in your second select from a left join b and if you want to oder by how it is in table b then in first select select from a left join b and in your second select from b left join a .

Here is a demo with the last requested samle data.

You could try using a some union and left join

select  A.name, case when is null t1.name then 'newly addedd' end 
from A 
left  JOIN  (
  select  A.name from A 
  union B.name from B
) t1 

union 
select  B.name, case when is null t1.name then 'delete' end 
from B
left  JOIN  (
  select  A.name from A 
  union B.name from B
) t1 

please try with below query ( SQL FIDDLE ):

CREATE PROCEDURE update_records
AS
BEGIN
    INSERT INTO C(name, status)
    SELECT AB.name, AB.status FROM(
    SELECT (case when A.name is null then B.name else A.name end) as name,
       (CASE 
        WHEN A.name is null THEN 'newly added'
        WHEN B.name is null THEN 'removed'
     END) AS status
    FROM A
    FULL JOIN B on B.name = A.name
  ) as AB
  ORDER by AB.name

END

You should use FULL OUTER JOIN.

DECLARE @table1 TABLE(
    [name] char(1)
)
DECLARE @table2 TABLE(
    [name] char(1)
)
INSERT INTO @table1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G')
INSERT INTO @table2 VALUES ('A'),('B'),('Q'),('C'),('D'),('F'),('G')
SELECT 
    IIF(T1.name IS NULL,T2.name,T1.name) as 'Name',
    CASE WHEN T1.name IS NULL THEN 'newly added' WHEN T2.name IS NULL THEN 'removed' ELSE '' END as 'Status'
FROM @table1 T1
FULL OUTER JOIN @table2 T2 ON T1.name = T2.name

There ise one more possible method:

DECLARE @table1 TABLE(
    [name] char(1)
)
DECLARE @table2 TABLE(
    [name] char(1)
)
INSERT INTO @table1 VALUES ('A'),('B'),('C'),('D'),('E'),('F'),('G')
INSERT INTO @table2 VALUES ('A'),('B'),('Q'),('C'),('D'),('F'),('G')
SELECT 
    T1.name as 'Full_List',
    IIF(T2.name IS NOT NULL,'','removed') as 'Status'
FROM @table1 T1 
LEFT OUTER JOIN @table2 T2 ON T1.name = T2.name
UNION ALL
SELECT 
    T2.name,
    IIF(T1.name IS NULL,'Added','') 

FROM @table2 T2 
LEFT OUTER JOIN @table1 T1 ON T1.name = T2.name
WHERE T1.name IS NULL

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