2017-05-31 14 views
0

我試圖找到確定員工升級所需時間的方法。使用SQL查找員工時間級別更改

我有兩個表:

EMPLOYEE_DAILY:包含員工數據的日常快照。

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在L1 晉升爲L2聘請了1/1/2015於2015年3月5日 葉在2015年4月1日 公司在重新聘用的2017年1月1日L1 晉升爲L2上2017年3月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 

我相信我的查詢會查看2017年3月1日的促銷活動並提取2015年1月1日的日期,但我真正想要的是查詢會顯示各個促銷級別之間的時間,因此3/5/2015 - 1/1/2015和3/1/2017 - 1/1/2017。

+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