2016-10-26 34 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

相关问题