従業員ステータス履歴テーブルがあります。従業員の最新の採用者の列を更新します
私は従業員が再雇用されるまで、それぞれの行に分(EffectiveStartDate)をコピーしなければならないもう一つの列を作成する必要があります。 UIで日付が渡される従業員のサービスの長さを取得する必要があります。
どのように私はこの答えは、いくつかの仮定を持っているSQLサーバー2014
従業員ステータス履歴テーブルがあります。従業員の最新の採用者の列を更新します
私は従業員が再雇用されるまで、それぞれの行に分(EffectiveStartDate)をコピーしなければならないもう一つの列を作成する必要があります。 UIで日付が渡される従業員のサービスの長さを取得する必要があります。
どのように私はこの答えは、いくつかの仮定を持っているSQLサーバー2014
で達成することができます。
仮定
データセットは、同時に複数の従業員のためのものです。そうでない場合は、 とEmployeeID
のような別の列がある場合、 はの中のover
句の中でそれを指定したいと思います。
EmployeeStatusCatalog
値は以下の意味を持っていることを
"または" 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
が戻ったばかりのチェックと私は与えた答えは十分に明確だったかどうかを確認したかった、またはあなたはそれにそれ以上の質問があった場合。その答えがあなたが探していたものであれば、先に進んで答えを受け入れます(答えにチェックマークを付ける)。 – tarheel