2016-10-26 35 views
1

我正在使用MS SQL Server 2014.我有一張跟蹤員工的表格,並且每次在應用程序中進行更改時都會生成一個生效日期集並插入一個新行,看起來像這樣。根據變更和生效日期編制具有開始日期和結束日期的表格

ID EmployeeID Job Title  Effective Date 
1 10   Sales Agent  10/1/2016 
3 10   Sales Agent  10/5/2016 
7 10   Sales Agent 2 10/15/2016 
9 10   Sales Agent 3 10/20/2016 
15 10   Sales Agent 3 10/16/2016 
2 2   BSA III   10/1/2016 
4 2   BSA II   10/1/2016 
14 2   BSA III   10/1/2016 

我需要通過該表進行迭代,如果有插入職務的變化與新的開始和結束日期一新行,如果沒有一個新的標題則忽略的變化,除非它覆蓋上一行的生效日期。員工組的最後一行應設置爲1/1999的結束日期。我有SSIS或SQL我可以做到這一點,但我只是不知道從哪裏開始或如何把它關閉。該過程完成後,表格結果應如下所示。

EmployeeID Job Title  Start Date End Date 
10   Sales Agent  10/1/2016 10/14/2016 
10   Sales Agent 2 10/15/2016 10/15/2016 
10   Sales Agent 3 10/16/2016 1/1/2999 
2   BSA III   10/1/2016 1/1/2999 
+2

最後一行的「職位」應該是「銷售代理3」的權利? – FLICKER

+0

@ FLICKER是的,它應該。謝謝,我已經更新了這個問題。 – ScholarYoshi

+0

@Beth不行,因爲行ID 15覆蓋行ID 9具有較早的生效日期。 – ScholarYoshi

回答

1

這應該讓你得到你需要的答案以及允許多個有效時間段爲同一個工作。

DROP TABLE #EMP 
DROP TABLE #EMPFINAL 
Create table #EMP (EmployeeID INT, 
      JOBTitle VARCHAR(30), 
      EffectiveDate Date 
      ) 

Create table #EMPFINAL (EmployeeID INT, 
      JOBTitle VARCHAR(30), 
      StateDate Date, 
      ENDDATE Date 
      ) 

INSERT INTO #EMP 
values (10,'Sales Agent', '2016-10-1') 
,(10,'Sales Agent', '2016-10-5') 
,(10,'Sales Agent 2', '2016-10-15') 
,(10,'Sales Agent 3', '2016-10-20') 
,(10,'Sales Agent 3', '2016-10-16') 


DECLARE @EMPID INT, 
     @JOBTITLE VARCHAR(30), 
     @EFFECTIVE DATE, 
     @MAXEFF DATE, 
     @MAXEMPID INT, 
     @MAXJOB VARCHAR(30) 


DECLARE REV CURSOR FOR 
SELECT EMPLOYEEID, JOBTITLE,EFFECTIVEDATE 
FROM #EMP 
order by effectivedate 

OPEN REV 

FETCH NEXT FROM REV 
INTO @EMPID, @JOBTITLE,@EFFECTIVE 

WHILE @@FETCH_STATUS = 0 
BEGIN 

SET @MAXEFF = (SELECT ISNULL(MAX(EndDate),'1900-01-01') FROM #EMPFINAL WHERE EmployeeID = @EMPID) 
SET @MAXEMPID = (SELECT MAX(EMPLOYEEID) FROM #EMPFINAL WHERE ENDDATE = @MAXEFF) 
SET @MAXJOB = (SELECT MAX(JOBTitle) FROM #EMPFINAL WHERE ENDDATE = @MAXEFF) 

IF @MAXEFF = '1900-01-01' 
BEGIN 
    INSERT INTO #EMPFINAL 
    VALUES(@EMPID,@JOBTITLE,@EFFECTIVE,'2999-01-01') 

END 

IF @MAXEMPID = @EMPID and @MAXJOB != @JOBTITLE 
BEGIN 

    UPDATE #EMPFINAL 
    SET ENDDATE = DATEADD(dd,-1,@Effective) 
    where ENDDATE = '2999-01-01' 
    and JOBTitle != @JOBTITLE 

    INSERT INTO #EMPFINAL 
    VALUES(@EMPID,@JOBTITLE,@EFFECTIVE,'2999-01-01') 
END 


FETCH NEXT FROM REV 
INTO @EMPID, @JOBTITLE,@EFFECTIVE 

END 

CLOSE REV; 
DEALLOCATE REV; 

Select * 
From #EMPFINAL 
0

創建測試數據:

select * into #t 
from (
select 
1 ID, 10 EmployeeID, 'Sales Agent' JobTitle, cast('10/1/2016' as date) EffectiveDate 
union select 3 ,10 ,'Sales Agent'  ,'10/5/2016' 
union select 7 ,10 ,'Sales Agent 2' ,'10/15/2016' 
union select 9 ,10 ,'Sales Agent 3' ,'10/20/2016' 
union select 15 ,10 ,'Sales Agent 3' ,'10/16/2016' 
union select 2 ,2 ,'BSA III'   ,'10/1/2016' 
union select 4 ,2 ,'BSA II'   ,'10/1/2016' 
union select 14 ,2 ,'BSA III'   ,'10/1/2016' 
) a 

代碼:

;with cc as (
select ID, EmployeeID, JobTitle, EffectiveDate 
    , LEAD(JobTitle) over (partition by EmployeeID order by EffectiveDate, ID) NextJobTitle 
    , LAG(EffectiveDate) over (partition by EmployeeID, JobTitle order by EffectiveDate, ID) StartDate 
    , LEAD(EffectiveDate) over (partition by EmployeeID order by EffectiveDate, ID) EndDate 
    from #t 
) 
, c2 as (
    select ID, EmployeeID 
    , JobTitle 
    , EffectiveDate 
    , NextJobTitle 
    , StartDate 
    , dateadd(day, -1, EndDate) EndDate 
from cc 
) 
, c3 as (
select 
    EmployeeID, JobTitle 
    , IsNull(StartDate, EffectiveDate) as StartDate 
    , IsNull(EndDate, '2999-01-01') as EndDate 
from c2 
where JobTitle <> NextJobTitle or NextJobTitle is null 
) 
select * 
from c3 
where StartDate <= EndDate 

結果:

╔════════════╦═══════════════╦════════════╦════════════╗ 
║ EmployeeID ║ JobTitle  ║ StartDate ║ EndDate ║ 
╠════════════╬═══════════════╬════════════╬════════════╣ 
║ 2   ║ BSA III  ║ 2016-10-01 ║ 2999-01-01 ║ 
╠════════════╬═══════════════╬════════════╬════════════╣ 
║ 10   ║ Sales Agent ║ 2016-10-01 ║ 2016-10-14 ║ 
╠════════════╬═══════════════╬════════════╬════════════╣ 
║ 10   ║ Sales Agent 2 ║ 2016-10-15 ║ 2016-10-15 ║ 
╠════════════╬═══════════════╬════════════╬════════════╣ 
║ 10   ║ Sales Agent 3 ║ 2016-10-16 ║ 2999-01-01 ║ 
╚════════════╩═══════════════╩════════════╩════════════╝ 
+0

嗨閃爍,感謝您的回答,但我的示例數據是正確的。稍後添加的插入(更高的ID號)應該能夠覆蓋更改,如果其生效日期更早到達。 – ScholarYoshi

+0

尼斯使用的超前和滯後,我只有2008,所以我做了一個光標:( –

+0

大ID與小EFFECTIVEDATE?這是一種不同尋常的。我看你已經改變了您的樣本數據。我儘量調整我的答案。 – FLICKER

相關問題