有人可以帮我理解使用哪种功能或方向去解决下面的问题?我已经完成了脚本的大部分工作,但我仍然试图弄清楚如何从上到下一次定义一个日期。例如,计算第一行的第一个日期,然后根据第一行的第一个日期计算第二行的第二个日期。
我创建的示例表:
Employee | WorkDate | #ofBreaksInWks | EndDate | StartDate
123 1/4/2016 1/4/2016
123 1/5/2016
123 1/6/2016 2
123 1/27/2016
123 1/28/2016 5 *1/28/2016 *3/10/2016
123 3/10/2016
123 3/9/2016 1
123 3/25/2016
123 4/1/2016
123 4/10/2016
123 4/15/2016 4
= Today's date *05/15/2016
= Values with asterisk* will be calculative
如果我工作4周或<13周,那么我需要根据工作量为员工分配结束日期。
MIN
"1/4/2016"
WorkDate
减去StartDate
(1/28/2016
- 3/10/2016
)。如果大于5周,则指定结束日期为WorkDate
。4/15/2016
- *05/15/2016
),所以我会计算一下员工是否工作超过4周。在这种情况下,员工已经工作了5周。按之前的StartDate
3/10/2016
减去4/15/2016
(WorkDate
)计算。我知道如何计算开始日期和结束日期,但我不确定如何一次完成这个日期,因为每个下一行都取决于之前的值。请帮忙!
答案 0 :(得分:1)
您可以使用Temp Table和具有Processed标志的While循环来实现您想要的效果。
IF (OBJECT_ID('tempdb..#YourTempTable') IS NOT NULL)
BEGIN
DROP TABLE #YourTempTable;
END
-- Populate Temp Table
SELECT
Processed = 0,
Id,
Employee,
WorkDate,
EndDate,
StartDate
INTO
#YourTempTable
FROM
DataSourceTable;
DECLARE @Id int = 0;
DECLARE @LastId int = 0;
DECLARE @Employee nvarchar(30) = '';
DECLARE @WorkDate int = 0;
DECLARE @LastWorkDate int = 0;
WHILE EXISTS (SELECT TOP 1 Processed FROM #YourTempTable WHERE Processed = 0)
BEGIN
SELECT TOP 1
@Id = Id,
@Employee = Employee,
@WorkDate = WorkDate
FROM
#YourTempTable
WHERE
Processed = 0;
UPDATE
DataSourceTable
SET
NewDefinedDate = @WorkDate -- Combined with something with @LastWorkDate
WHERE
Id = @Id;
SET @LastId = @Id;
SET @LastWorkDate = @LastWorkDate;
UPDATE
#YourTempTable
SET
Processed = 1
WHERE
Id = @Id;
END
END
IF (OBJECT_ID('tempdb..#YourTempTable') IS NOT NULL)
BEGIN
DROP TABLE #YourTempTable;
END
答案 1 :(得分:0)
;with weeks as (
select
Employee,
datediff(week, '20000102', WorkDate) as weekNum,
min(WorkDate) as workDate,
row_number() over (
partition by Employee
order by datediff(week, '20000102', WorkDate)
) as rowNum
from emp
group by Employee, datediff(week, '20000102', WorkDate)
), islands as (
select
Employee,
min(workDate) as workDate,
datediff(week, min(workDate), max(workDate)) + 1 as workWeeks
from weeks
group by Employee, weekNum - rowNum
), gaps as (
select *,
datediff(week,
workDate,
lead(workDate) over (partition by Employee order by workDate)
) - workWeeks as breakWeeks
from islands
)
select * from gaps
-- where breakWeeks > workWeeks; ??
我仍然不明白这个问题的全部性质,但这是我几天前在手机上输入的上一次尝试的工作版本。它确定连续工作周数的周数,然后计算自身与下一次运行开始之间的非工作周数。这是解决问题的非循环方法。希望它能让您更接近解决方案。