Транспонировать несколько столбцов в строку, найти, какие данные изменены, сохранить старое значение, если изменений нет

#sql #sql-server

#sql #sql-сервер

Вопрос:

OriData

  ------------ ------------------- ------- -------- ------------- ---------- ------------ --------------- ------------ -------------- 
|  Ori_Date  | Resubmission_Date | SeqNo |  IDNO  | PX_Name_OLD | Name_NEW | NameReason | PX_Gender_OLD | Gender_New | GenderReason |
 ------------ ------------------- ------- -------- ------------- ---------- ------------ --------------- ------------ -------------- 
| 2019-01-01 | 2019-01-03        | A123  | ID123  | OldName     | NewName  | Valid      | L             | P          | Valid        |
| 2019-02-01 | 2019-02-03        | AB456 | A26589 | Captain     | IronMan  | Valid      | L             |            |              |
 ------------ ------------------- ------- -------- ------------- ---------- ------------ --------------- ------------ -------------- 
  

Результат, который я хочу

  ------------ ------------------- ------- -------- --------- ------------ ---------- --------- ------------ -------- -------------- 
|  Ori_Date  | Resubmission_Date | SeqNo |  IDNo  | Col_Chg | From_Value | To_Value |  Name   | NameReason | Gender | GenderReason |
 ------------ ------------------- ------- -------- --------- ------------ ---------- --------- ------------ -------- -------------- 
| 2019-01-01 | 2019-01-03        | A123  | ID123  | Name    | OldName    | NewName  | NewName | Valid      | P      | NULL         |
| 2019-01-01 | 2019-01-03        | A123  | ID123  | Gender  | L          | P        | NewName | NULL       | P      | Valid        |
| 2019-02-01 | 2019-02-03        | AB456 | A26589 | Name    | Captain    | IronMan  | IronMan | Valid      | L      | NULL         |
 ------------ ------------------- ------- -------- --------- ------------ ---------- --------- ------------ -------- -------------- 
  

Запрос, который я написал:

 select Seqno, IDNo, ColName, Vals
from 
    (
        select  
                isnull(cast(reqid as nvarchar(255)), '') AS Seqno,
                isnull(cast(Name collate database_default as nvarchar(255)), '') as Name,
                isnull(cast(IDNo collate database_default as nvarchar(255)), '') as IDNo,
                isnull(cast(Gender collate database_default as nvarchar(255)), '') as Gender
        from #A
        where NameReason IS NOT NULL or GenderReason IS NOT NULL
    ) unpivot_table
    unpivot
        (
            vals for colname in (Name, Gender
        )
    ) unpivot_handle
  

Всякий раз, когда есть значение в NameReason / GenderReason, то это вызовет изменения, вот почему в запросе я указываю NameReason или GenderReason НЕ РАВНО NULL.

PX = Table1-старое значение, xx_New = Таблица 2-новое значение (если есть — но определенно есть обновление для некоторых столбцов), я объединил их вместе и вставил в таблицу # A.

Столбец Name, если есть изменения, примет столбец New_Name.

Столбец Gender, если изменений нет, примет PX_Gender, он же старое значение.

С моим запросом я не могу получить From_Value , To_Value и другие столбцы. Есть идеи, как получить желаемый результат?

Примечание: Я имею дело с 10 миллионными записями, 20 cols, я не могу это жестко закодировать.

Комментарии:

1. Я не понимаю ваших желаемых результатов. Почему пол указан как в столбцах, так и в дополнительной строке?

2. @GordonLinoff если есть изменения, покажите новый результат во всех строках (с тем же idno). как вы можете видеть из idno: A26589, для пола изменений нет, поэтому желаемый результат показывает старое значение вместо этого.

Ответ №1:

Я думаю, вы хотите этого:

 select a.Ori_Date, a.Resubmission_Date, a.SeqNo, a.IDNO,
       v.*
from #a a cross apply
     (values ('Name', PX_Name_OLD, Name_NEW, NameReason),
             ('Gender', PX_Gender_OLD, Gender_New, GenderReason)
     ) v(Col_Chg, From_Value, To_Value, Reason)
where reason is not null;
  

Примечание: Сюда не входят все имеющиеся у вас столбцы. Дополнительные столбцы gender кажутся избыточными.

Комментарии:

1. результат почти достигнут, но теперь у меня возникла новая проблема. он показывает все столбцы, которые даже без изменений. я попытался поиграть с «условием where», но по-прежнему безуспешно. потому что я отслеживаю только то, что если столбец ‘reason’ не равен null, это определенно означает, что столбец получил изменения. даже если FX_Occupation_old = значение: A, в Occupation_new = значение: B, но occupationReason равен null, тогда никаких изменений.

2. @user3542587 . . . Это основано на where предложении. Возможно, это должно быть связано с причиной, а не со значениями.