此代码有效,但似乎结果在1天后就消失了
目标:找到给定的两个日期的datediff。
但是,我们将不得不排除
示例
2017-11-04 00:00:00和2017-11-22 10:21:00之间的区别
预期结果:12.42(3个周六和周日除外)
当前结果:13.42
该代码不是我编写的,因此我正在尝试理解它。我评论了一些我也不清楚的部分。
/**This part is to find the difference in time for the two dates**/
DECLARE @temp AS DECIMAL(10,2) = CAST(DATEDIFF(hour, CONVERT(time, @StartDate), CONVERT(time, @ENDDate)) as Decimal(10,2))/24.00
Declare @numdays int=0
/**This part is to find the difference in date for the two dates**/
/**Issues likely to come from here**/
IF DATEDIFF(day,@StartDate,@ENDDate)>0
BEGIN
WHILE DATEDIFF(day,@StartDate,@ENDDate)>0
BEGIN
SET @StartDate=DATEADD(d,1,@StartDate)
WHILE exists (SELECT Holiday_Date FROM Holiday where Holiday_Date=CONVERT(date, @StartDate)) or DATENAME(DW,@StartDate)='saturday' or DATENAME(DW,@StartDate)='sunday'
BEGIN
SET @StartDate=DATEADD(d,1,@StartDate)
/**Exclude weekends and PH so we do not add numDays here **/
END
SET @numDays=@numDays+1
END
END
/**Omitted some irrelevant codes here**/
/**Add both differences together to get final result**/
DECLARE @result AS DECIMAL(10,2) = @temp + @numDays
RETURN @result
正在考虑只纠正逻辑而不是重写整个代码。谢谢!
答案 0 :(得分:2)
就像已经提到的,最好的方法是创建一个Calendar Table,然后使用“工作日”列或您所谓的“工作日”列来计算差异。
这是伪SQL,没有有效的日历表,但应该可以帮助您:
SELECT YT.{YourColumn},
WD.WorkingDays
FROM YourTable YT
CROSS APPLY (SELECT COUNT(CT.DateKeyColumn) -1 AS WorkingDays --Minus 1, as we don't want to include the first day
FROM CalendarTable CT
WHERE CT.[DateColumn] >= YT.StartingDateColumn
AND CT.[DateColumn] <= YT.EndingDateColumn
AND CT.WorkingDay = 1) WD
答案 1 :(得分:1)
您提到的代码基本上在伪代码中执行以下操作:
while i between @StartDate and @ENDDate
begin
increment i by 1
increment i until it is not a holiday
add one day to result
end
return result
我的看法是这段代码难看且效率低下。
您遇到的麻烦中90%是创建日历表;但您已经有一个。不要使用此功能;将代码更改为Larnu的建议。如果您遇到困难,请询问我们进一步的澄清。
答案 2 :(得分:0)
在MySQL 5.1中测试: MySQL的“工作日”函数对Mon返回0,对SAT返回5,对SUN返回6,因此您在下面的SQL中看到了一些不可思议的数字。与5和6。
示例:
select floor((datediff (ed, st)+1) / 7)*2 /*complete week's weekends*/
+ case when floor((datediff (ed, st) +1) % 7) between 0 and 6 /*additional weekends besides complete weeks*/
then case when weekday(ed) >= weekday(st) then least(floor((datediff (ed, st) +1) % 7), greatest(least(6, weekday(ed)) - greatest(5, weekday(st)) + 1,0))
else least(floor((datediff (ed, st) +1) % 7), greatest(least(6, weekday(ed)+7) - greatest(5, weekday(st)) + 1,0)) end
else 0
end as num_of_sat_and_sun
from (select '2019-01-07' as st, '2019-01-12' as ed) x