Pergunta

I have two tables with below structure :

Create table Customer_info
(Customer_num  varchar(50),
 Customer_Branch  int);

Create table Customer_Transaction_Info
(Customer_num     varchar(50),
 Branch_Code      int,
 Trns_Measure_One int,
 Trns_Measure_Two int
 );

Sample data for each table:

insert into Customer_info(Customer_num , Customer_Branch)
values('A',1),
      ('B',2),
      ('C',3);

   Customer_num     Customer_Branch
------------------- ---------------
     A                      1
     B                      2
     C                      3

insert into Customer_Transaction_Info (Customer_num,Branch_Code,Trns_Measure_One,Trns_Measure_Two)
Values ('A',1,10,0),
       ('A',2,20,5),
       ('A',3,14,0),
       ('B',2,10,10),
       ('B',1,36,0),
       ('C',3,14,0),
       ('C',1,10,18);

 Customer_num    Branch_Code Trns_Measure_One Trns_Measure_Two
 --------------- ----------- ----------------  ---------------
    A               1           10               0
    A               2           20               5
    A               3           14               0
 -------------------------------------------------------------
    B               2           10               10
    B               1           36               0
 -------------------------------------------------------------
    C               3           14               0
    C               1           10               18

What I need to do is this:

  1. For each Customer_num in Customer_Transaction_Info , Trns_Measure_Two must be assigned to the correct Branch_Code for that customer which is the one in the first table , Customer_info

  2. For each Customer_num in Customer_Transaction_Info, Trns_Measure_Two must be updated to 0 for incorrect branches.

So based on these the desired result is below:

 Customer_num    Branch_Code Trns_Measure_One Trns_Measure_Two
 --------------- ----------- ----------------  ---------------
    A               1           10               0---> Update to 5
    A               2           20               5---> Update to 0
    A               3           14               0
 -------------------------------------------------------------
    B               2           10               10---> This record is Correct
    B               1           36               0
 -------------------------------------------------------------
    C               3           14               0 ---> Update to 18
    C               1           10               18---> Update to 0

We must take these facts into consideration that:

  1. There's only one Customer_Branch for each Customer_num in Customer_info table.
  2. There's only one non-zero Trns_Measure_Two for each Customer_num in Customer_Transaction_Info

Thanks in advance

Foi útil?

Solução

UPDATE Customer_Transaction_Info
SET Trns_Measure_Two = subquery.Trns_Measure_Two
FROM (SELECT cti.Customer_num, cti.Branch_Code, cti.Trns_Measure_One,
             CASE WHEN ci.Customer_Branch = cti.Branch_Code
                  THEN MAX(cti.Trns_Measure_Two) OVER (PARTITION BY cti.Customer_num)
                  ELSE 0
                  END Trns_Measure_Two
      FROM Customer_info ci
      JOIN Customer_Transaction_Info cti ON ci.Customer_num = cti.Customer_num) subquery
WHERE Customer_Transaction_Info.Customer_num = subquery.Customer_num
  AND Customer_Transaction_Info.Branch_Code = subquery.Branch_Code

fiddle

Outras dicas

This should solve the first requirement:

UPDATE CTI.Trns_Measure_Two -- Updating Customer_info.Trns_Measure_Two
SET CTI.Trns_Measure_Two = CTI2.Trns_Measure_Two -- Set it to the correct value (the only non-zero value for that Customer_num)
FROM Customer_Transaction_Info AS CTI
INNER JOIN Customer_info AS CI -- Inner joining Customer_info to ensure we only update for the correct Customer and Branch
    ON CTI.Customer_num = CI.Customer_num
    AND CTI.Branch_Code = CI.Customer_Branch
INNER JOIN Customer_Transaction_Info AS CTI2 -- Need to re-join to Customer_Transaction_Info on Customer_num and Trns_Measure_Two <> 0 to get this customer's non-zero correct value
    ON CTI.Customer_num = CTI2.Customer_num
    AND CTI2.Trns_Measure_Two <> 0

This should update the incorrect branches for your second requirement:

UPDATE CTI.Trns_Measure_Two -- Updating Customer_info.Trns_Measure_Two
SET CTI.Trns_Measure_Two = 0 -- Setting incorrect values to 0
FROM Customer_Transaction_Info AS CTI
LEFT JOIN Customer_info AS CI -- Left joining to Customer_info so we can see where there's no match by Customer_num and Customer_Branch
    ON CTI.Customer_num = CI.Customer_num
    AND CTI.Branch_Code = CI.Customer_Branch
WHERE CI.Customer_num IS NULL -- This filters Customer_Transaction_Info to only the bad records (where there's no match to Customer_info)

Please see the comments for information on how these two update statements work.

update a
set a.Trns_Measure_Two = case
                            when b.Trns_Measure_Two is null then 0
                            else b.Trns_Measure_Two end
  from Customer_Transaction_Info a
  left join (select t1.Customer_num, t1.Customer_Branch, t2.Trns_Measure_Two
               from Customer_info t1
              inner join (select distinct i.Customer_num, i.Trns_Measure_Two
                           from Customer_Transaction_Info i
                          where i.Trns_Measure_Two > 0) t2
                 on t1.Customer_num = t2.Customer_num) b
    on a.Customer_num = b.Customer_num
   and a.Branch_Code = b.Customer_Branch;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a dba.stackexchange
scroll top