INSERT INTO на основе SELECT и версионной записи - PullRequest
2 голосов
/ 19 февраля 2020

У меня есть таблица, которая содержит текущее состояние сотрудников, как показано ниже:

 SELECT EmployeeId ,OfficeId from EmpCurrent

Вывод, как показано ниже:

EmployeeId OfficeId
54          67
64          57
89          23

И у меня есть другая таблица, содержащая полную историю для сотрудника, за исключением OfficeId, который не записан в историю (я добавил столбец OfficeId, который должен быть пустым для вставки из EmpCurrent):

SELECT EmployeeId ,Func AS [Function],OfficeId,Version from EmpHistory

Вывод подобен приведенному ниже для EmployeeId = 54:

EmployeeId Function OfficeId Version
54         Manager  NULL     1
54         Director NULL     2
54         HeadOf   NULL     3

Я хочу получить OfficeId от EmpCurrent и вставить его в EmpHistory в последней версии (максимальная версия) каждого сотрудника, мой вывод будет таким, как показано ниже:

EmployeeId Function OfficeId Version
54         Manager  NULL     1
54         Director NULL     2
54         HeadOf   67       3

Ответы [ 3 ]

2 голосов
/ 19 февраля 2020

демо на дб <> скрипка

Во-первых, Вам необходимо получить 3 поля h.EmployeeId, c.OfficeId, max(Version) as MaxVersion.

Во-вторых, Обновление h.OfficeId = cte.OfficeId в #EmpHistory таблица с 2 условиями h.EmployeeId = cte.EmployeeId and MaxVersion = h.Version

Полный код

;with cte as( 
select h.EmployeeId, c.OfficeId, max(Version) as MaxVersion
from #EmpHistory h
inner join #EmpCurrent c on h.EmployeeId = c.EmployeeId
group by h.EmployeeId, c.OfficeId
)

update h
set h.OfficeId = cte.OfficeId
from #EmpHistory h
inner join cte on h.EmployeeId = cte.EmployeeId and MaxVersion = h.Version

Выход

enter image description here

2 голосов
/ 19 февраля 2020
;WITH CTE_EMP
AS
(
    SELECT 
        EH.EmployeeId
        ,Version        = MAX(Version)
    FROM
        EmpHistory AS EH
    GROUP BY
        EH.EmployeeId
)
select 
     EH.EmployeeId
    ,EH.Func
    ,OfficeId       = CASE WHEN CTE.Version = EH.Version THEN EC.OfficeId END
    ,EH.Version
from 
    EmpHistory AS EH 
    LEFT OUTER JOIN EmpCurrent AS EC ON EC.EmployeeId = EH.EmployeeId
    LEFT OUTER JOIN CTE_EMP AS CTE ON CTE.EmployeeId = EH.EmployeeId
2 голосов
/ 19 февраля 2020

Если вам нужно самое последнее значение для join, то:

select eh.*, ec.officeid
from (select eh.*,
             row_number() over (partition by employeeid order by version desc) as seqnum
      from emphistory eh
     ) eh left join
     empcurrent ec
     on ec.employeeid = eh.employeeid and eh.seqnum = 1;

Это один из необычных случаев, когда вы фильтруете таблицу first в left join. Вы также можете сделать это как:

select eh.*,
       (case when eh.seqnum = 1 then ec.officeid end) as officeid
from (select eh.*,
             row_number() over (partition by employeeid order by version desc) as seqnum
      from emphistory eh
     ) eh left join
     empcurrent ec
     on ec.employeeid = eh.employeeid ;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...