我正在使用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
答案 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 ║
╚════════════╩═══════════════╩════════════╩════════════╝