根据更改和生效日期

时间:2016-10-26 19:52:01

标签: sql-server ssis

我正在使用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/1/2999。我有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 个答案:

答案 0 :(得分: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

答案 1 :(得分: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 ║
╚════════════╩═══════════════╩════════════╩════════════╝