Сравните две таблицы и вставьте все записи с добавленным или удаленным состоянием в 3-ю таблицу, используя SQL Серверная процедура - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть таблица A и таблица B. Я должен сравнить записи этой таблицы и вставить данные в таблицу C, используя SQL Серверная процедура в следующем формате

таблица A

  name
  A
  B
  C
  D
  E
  F
  G

таблица B

  name
  A
  B
  Q
  C
  D
  F
  G

таблица c должна быть как ниже. у него есть дополнительное поле 'status', чтобы упомянуть, что запись добавлена ​​или удалена.

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

Я знаю, что мы можем сравнить 2 таблицы и найти добавленные или удаленные записи, используя операции EXCEPT и UNION. Но в этом случае я должен объединить эти записи с неизмененными записями и должен поместить добавленные или удаленные записи в правильное положение.

Ответы [ 5 ]

4 голосов
/ 05 февраля 2020

Это можно сделать с помощью full join и условных логи c:

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

Демонстрация на DB Fiddle :

name | status     
:--- | :----------
A    | <em>null</em>       
B    | <em>null</em>       
C    | <em>null</em>       
D    | <em>null</em>       
E    | removed    
F    | <em>null</em>       
G    | <em>null</em>       
Q    | newly added
1 голос
/ 05 февраля 2020

В зависимости от того, какой заказ вы хотите выполнить sh в конце, вы можете использовать это:

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);

А затем, если вы хотите сделать заказ, как в таблице а, то сначала выберите выберите from b left join a, а во втором выберите from a left join b, и если вы хотите заказать в порядке, указанном в таблице b, в первом выберите from a left join b, а во втором выберите from b left join a.

* 1010. * Вот демоверсия с последними запрашиваемыми данными выборки.

0 голосов
/ 05 февраля 2020

Вы должны использовать 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

Есть еще один возможный метод:

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


0 голосов
/ 05 февраля 2020

пожалуйста, попробуйте следующий запрос (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
0 голосов
/ 05 февраля 2020

Вы можете попробовать использовать какое-нибудь объединение и оставить левое соединение

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 
...