2017-05-31 4 views
0

私は、従業員のレベルアップにどれくらいの時間がかかるかを判断する手段を探しています。SQLを使用して従業員のタイム・レベルを変更する

EMPLOYEE_DAILY:従業員データの日々のスナップショットが含まれています

は、私は2つのテーブルを持っています。

EMP_HISTORY:プロモーションイベント、現在の(プロモーション前)レベル、プロモーションレベル、およびプロモーションの日付が含まれます。

私の最初の解決策は、EMP_HISTORYテーブルのプロモーションイベントを見てから、EMPLOYEE_DAILYテーブルの昇格前のレベルにある従業員の最初の日付を取得し、その日をプロモーション日付から差し引いて従業員がレベルアップするまでに要した時間。

従業員が退職してから(時には複数回)返すことがあるため、私の方法に問題があります。従業員が以前の雇用サイクルにあった場合、その従業員がCURRENT_LEVELにあった最初の日付を取得しますレベルアップする時間)。

WITH LEVEL_DATES AS 
(
SELECT 
    EMPLOYEE_ID, 
    EMPLOYEE_LEVEL, 
    MIN(AS_OF_DATE) AS MIN_LEVEL_DATE 
FROM EMPLOYEE_DAILY 
) 
SELECT 
    H.EMPLOYEE_ID, 
    H.PROCESS_TYPE, 
    H.CURRENT_LEVEL, 
    H.PROMOTION_LEVEL 
    H.EFFECTIVE_DATE, 
    LD.MIN_LEVEL_DATE 
FROM EMP_HIST H 
LEFT JOIN LEVEL_DATES LD 
ON H.EMPLOYEE_ID = LD.EMPLOYEE_ID 
AND H.PROMOTION_LEVEL != LD.EMPLOYEE_LEVEL 

時間変化の正確なデータをどのように得ることができるかについてのアイデアは誰でもありますが、事前昇格レベルの最初の日付は従業員の雇用期間内です。私はOracleデータベースで作業しています。

シナリオ例: 従業員1234は2015年3月5日 にL1 L2に昇進した時2015年1月1日に採用されたの2017年1月1日に再雇用2015年4月1日 に会社を辞めました

EMPLOYEE_DAILY: 
EMPLOYEE_ID EMPLOYEE_LEVEL AS_OF_DATE 
1234   L1    2015-03-02 
1234   L1    2015-03-03 
1234   L1    2015-03-04 
1234   L2    2015-03-05 

例データ:

EMPLOYEE_HIST: 
EMPLOYEE_ID EFFECTIVE_DATE CURRENT_LEVEL PROMOTION_LEVEL 
PROCESS_TYPE 

1234   2015-03-05  L1   L2 
PROMOTION 
年3月1日

例データにL2にプロモートL1

私のクエリは2011年3月1日のプロモーションを見て、2011年1月1日の日付をプルしますが、本当に欲しいのは、個々のプロモーションレベルの間に時間が表示されるため、2015年3月5日です - 2015年1月1日および2013年3月1日 - 2011年1月1日。

+1

「従業員がレベルアップするためにどのくらいの時間がかかります」。 。 。どういう意味ですか?サンプルデータと望ましい結果は、あなたがしたいことを明確にします。また、使用しているデータベースにタグを付けます。 –

+0

ゴードンありがとうございました。私はあなたが推薦したアイテムを追加しようとしました。 レベルの変更(私の例ではL1からL2へ)の間にかかる時間を探していますが、 – aguadamuz

答えて

0

私は、正確さや正しい構文を確認するために、これを実行しなかったが、あなたは試すことができます:

select 
    employee_id 
    ,earliest_as_of_date as effective_date 
    ,prev_employee_level as current_level 
    ,employee_level promotion_level 
from (
    select 
    employee_id 
    ,employee_level 
    ,case when lag(employee_id,1) over (order by employee_id, as_of_date) <> employee_id then null -- first row for an employee, can't be a promotion 
      when lag(employee_level,1) over (order by employee_id, as_of_date) = employee_level then null -- same level as previous row for this employee, is not a promotion 
      else lag(employee_level,1) over (order by employee_id, as_of_date) as prev_employee_level 
    ,min(as_of_date) over (partition by employee_id,employee_level) as earliest_as_of_date 
    from 
    employee_daily 
    group by 1,2 
) a 
where 1=1 
    and prev_employee_level is not null 
関連する問題