我一直是这个论坛的长期读者。它给了我很多帮助,但是我有一个问题,我无法找到特定于我的要求的解决方案。
我的任务是制定一个指标,以确定“员工绩效评估”过期的天数。数据采用以下格式:
EmployeeID LastEvalCompleteDate NextEvalDueDate
1001 2010-01-01 2010-11-01
1001 2010-11-20 2011-11-01
1001 2011-10-29 2012-11-15
1002 NULL 2013-12-01
根据上述示例数据,员工 1001 自2010-01-01以来已经有3次逃亡。员工 1002 已于今年开始,他的第一个评估将于2013-12-01完成。
我需要做的是将数据转换为这种格式:
EmployeeID EvalDueDate EvalCompleteDate DaysPastDue
1001 2010-11-01 2010-11-20 19
1001 2011-11-01 2011-10-29 -2
1001 2012-11-15 NULL 342 (based on today's date)
1002 2013-12-01 NULL -39 (based on today's date)
正如您所注意到的,我通过获取NextEvalDueDate
列的值并将其映射到新表中的EvalDueDate
列来派生新行。我还会将 NEXT行中的LastEvalCompleteDate
列中的值设为值,并将其映射到NextEvalDueDate
列。
我在迭代给定EmployeeID
的行时遇到问题。我尝试使用ROW_NUMBER() OVER (PARTITION BY ...)
,但它并没有把我带到任何地方。
我感谢任何帮助。谢谢。
答案 0 :(得分:1)
您使用ROW_NUMBER() OVER (PARTITION BY ...)
进入了正确的方向。不知道你在哪里卡住了,但它应该是这样的:
WITH CTE AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY NextEvalDueDate) RN
FROM dbo.Table1
)
SELECT
c1.EmployeeID
, c1.NextEvalDueDate AS EvalDueDate
, c2.LastEvalCompleteDate AS EvalCompleteDate
, DATEDIFF(DAY, c1.NextEvalDueDate, COALESCE(c2.LastEvalCompleteDate, GETDATE())) AS DaysPastDue
FROM CTE c1
LEFT JOIN CTE c2 ON c1.EmployeeID = c2.EmployeeID AND c1.RN = c2.RN - 1
ORDER BY c1.EmployeeID, c1.RN
答案 1 :(得分:0)
DECLARE @Results TABLE
(
EmployeeID INT NOT NULL,
RowNum INT NOT NULL,
PRIMARY KEY (RowNum, EmployeeID),
LastEvalCompleteDate DATE,
NextEvalDueDate DATE
);
INSERT @Results (RowNum, EmployeeID, LastEvalCompleteDate, NextEvalDueDate)
SELECT ROW_NUMBER() OVER(PARTITION BY e.EmployeeID ORDER BY e.LastEvalCompleteDate),
e.EmployeeID,
e.LastEvalCompleteDate,
e.NextEvalDueDate
FROM dbo.EmployeeEvaluation e;
WITH Base
AS
(
SELECT crt.RowNum,
crt.EmployeeID,
crt.NextEvalDueDate AS EvalDueDate,
nxt.LastEvalCompleteDate AS EvalCompleteDate
FROM @Results crt
LEFT JOIN @Results nxt ON crt.EmployeeID = nxt.EmployeeID AND crt.RowNum + 1 = nxt.RowNum
)
SELECT r.*,
DATEDIFF(DAY, r.EvalDueDate, ISNULL(r.EvalCompleteDate, GETDATE())) AS DaysPastDue
FROM Base r
ORDER BY r.EmployeeID, r.RowNum