2017-08-17 8 views
0

J'ai un tableau d'historique du statut de l'employé.mettre à jour une colonne avec le dernier employé d'un employé

EmployeeSTatusHistory

Je dois créer une colonne plus qui devrait copier le min (effectiveStartDate) sur chaque ligne jusqu'à ce que l'employé est réembauché. Je dois obtenir la durée du service de l'employé où la date sera passée par l'assurance-chômage.

NewCOlumn HireRehireDate

Comment puis-je obtenir dans le serveur SQL 2014

+0

Je voulais juste vérifier en arrière et voir si la réponse que je donnais était assez clair, ou si vous avez d'autres questions à ce sujet. Si la réponse est ce que vous cherchiez, allez-y et acceptez la réponse (cochez la case par la réponse) pour laisser ceux qui trébuchent sur cette question plus tard que c'était en fait la solution. – tarheel

Répondre

0

Cette réponse a quelques hypothèses.

hypothèses

  1. L'ensemble de données est seulement pour un employé à la fois. Si ce n'est pas, et il y a une autre colonne, comme EmployeeID, alors vous voulez vouloir spécifier que dans une clause partition by à l'intérieur de la clause over où mes commentaires le dénotent.

  2. Que les EmployeeStatusCatalog valeurs sont les suivantes:

    • A: Actif
    • L: Laissez (d'absence)
    • I: inactif
  3. Qu'une « location "ou la transaction" Rehire "est considérée comme ayant lieu soit au statut A initial, soit après qu'un statut I est terminé .

Configuration des données de l'échantillon

ne comprenait pas la colonne EmployeeStatusId, mon hypothèse est que ce n'est pas pertinent de créer le résultat attendu.

declare @employee table 
    (
     EffectiveStartDate date not null 
     , EffectiveEndDate date not null 
     , EmployeeStatusCatalog char(1) not null 
    ) 

insert into @employee 
    values ('2008-02-29', '2016-05-31', 'A') 
     , ('2016-06-01', '2016-06-30', 'A') 
     , ('2016-07-01', '2016-07-30', 'L') 
     , ('2016-07-31', '2016-09-02', 'A') 
     , ('2016-09-03', '2016-10-09', 'I') 
     , ('2016-10-10', '2016-11-01', 'A') 
     , ('2016-11-02', '2016-12-02', 'L') 
     , ('2016-12-03', '2016-12-05', 'I') 
     , ('2016-12-06', '2016-12-06', 'A') 
     , ('2016-12-07', '2017-01-01', 'L') 
     , ('2017-01-02', '9999-12-31', 'A') 

Réponse

Comme vous pouvez ou ne pouvez pas savoir, cela est un scénario gaps and islands classique. Où chaque segment entre les dates Hire/Rehire est une île (pas de lacunes dans cet exemple).

J'ai utilisé un CTE pour déplacer l'état I avant une ligne (via LAG fonction), puis obtenir le compte courant du nombre de lignes I pour donner à chaque île un nombre « ID ».

Après cela, utilisé une fonction min, lors du partitionnement par le numéro d'îlot, afin de déterminer le EffectiveStartDate minimum pour chaque îlot.

; with inactive_dts as 
    (
     --move the I status forward one row 
     select e.EffectiveStartDate 
     , e.EffectiveEndDate 
     , e.EmployeeStatusCatalog 
     , lag(e.EmployeeStatusCatalog, 1, 'A') over (/*partion by here*/ order by e.EffectiveStartDate asc) as prev_status 
     from @employee as e 
     where 1=1 
    ) 
    , active_island_nbr as 
    (
     --get the running count of the number of I rows 
     select a.EffectiveStartDate 
     , a.EffectiveEndDate 
     , a.EmployeeStatusCatalog 
     , a.prev_status 
     , sum(case a.prev_status when 'I' then 1 else 0 end) over (/*partition by here*/ order by a.EffectiveStartDate asc) as ActiveIslandNbr 
     from inactive_dts as a 
    ) 
select min(a.EffectiveStartDate) over (partition by a.ActiveIslandNbr) as HireRehireDate 
, a.EffectiveStartDate 
, a.EffectiveEndDate 
, a.EmployeeStatusCatalog 
from active_island_nbr as a 

Résultats

HireRehireDate EffectiveStartDate EffectiveEndDate EmployeeStatusCatalog 
2008-02-29  2008-02-29   2016-05-31  A 
2008-02-29  2016-06-01   2016-06-30  A 
2008-02-29  2016-07-01   2016-07-30  L 
2008-02-29  2016-07-31   2016-09-02  A 
2008-02-29  2016-09-03   2016-10-09  I 
2016-10-10  2016-10-10   2016-11-01  A 
2016-10-10  2016-11-02   2016-12-02  L 
2016-10-10  2016-12-03   2016-12-05  I 
2016-12-06  2016-12-06   2016-12-06  A 
2016-12-06  2016-12-07   2017-01-01  L 
2016-12-06  2017-01-02   9999-12-31  A