2017-08-17 19 views
0

従業員ステータス履歴テーブルがあります。従業員の最新の採用者の列を更新します

EmployeeSTatusHistory

私は従業員が再雇用されるまで、それぞれの行に分(EffectiveStartDate)をコピーしなければならないもう一つの列を作成する必要があります。 UIで日付が渡される従業員のサービスの長さを取得する必要があります。

NewCOlumn HireRehireDate

どのように私はこの答えは、いくつかの仮定を持っているSQLサーバー2014

+0

が戻ったばかりのチェックと私は与えた答えは十分に明確だったかどうかを確認したかった、またはあなたはそれにそれ以上の質問があった場合。その答えがあなたが探していたものであれば、先に進んで答えを受け入れます(答えにチェックマークを付ける)。 – tarheel

答えて

0

で達成することができます。

仮定

  1. データセットは、同時に複数の従業員のためのものです。そうでない場合は、 とEmployeeIDのような別の列がある場合、 はの中のover 句の中でそれを指定したいと思います。

    • A:アクティブ
    • L:まま(不在の)
    • 私は:非アク​​ティブ
    • 「レンタル
  2. EmployeeStatusCatalog値は以下の意味を持っていることを

  3. "または" Rehire "トランザクションは、Aの初期状態、またはIのステータスが終了した後に、 のいずれかが発生したとみなされます。

私の仮定は、それが期待される成果を作成するには関係がないということであるとして、サンプルデータセットアップ

は、EmployeeStatusId列が含まれていませんでした。

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

回答

あなたがよく、または知らないかもしれないとして、これは古典的なgaps and islandsシナリオです。 Hire/Rehire日付の間の各セグメントが島である(この例ではギャップがない)。

私は(LAG関数を介して)前方に一列にIステータスを移動し、各島に「ID」番号を与えるI行数のランニングカウントを取得するためにCTEを使用します。

その後、min関数を使用して島番号で区切って、各島の最小値はEffectiveStartDateとなりました。

; 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 

結果

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 
関連する問題