SQL服务器 创建函数来计算参数的2个日期之间的差值是我要从持续时间中排除的天数???
Blockquote
示例:从4-11-2018到29-11-2018,如果我通过星期日和星期一,则结果必须排除每个星期日和星期一,持续时间为 26(总天数)-8(排除天数)= 18天
答案 0 :(得分:0)
请给出以下解决方案,不确定是否是最好的解决方案,但强烈怀疑仍然存在简单的解决方案。
@from和@to日期包括在计算中。
如果需要更多信息,请留下评论。
在SqlServer上测试。
-- declare params
declare @from datetime = '2018-09-29 00:00:00.000'
declare @to datetime = getdate()
declare @param nvarchar(150) = 'Monday Wednesday'
declare @daysToSunstract int = 0
-- find days to substract based on @param
if (@param like '%Monday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -7, @to)/7-datediff(day, -6, @from)/7)
if (@param like '%Tuesday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -6, @to)/7-datediff(day, -5, @from)/7)
if (@param like '%Wednesday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -5, @to)/7-datediff(day, -4, @from)/7)
if (@param like '%Thursday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -4, @to)/7-datediff(day, -3, @from)/7)
if (@param like '%Friday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -3, @to)/7-datediff(day, -2, @from)/7)
if (@param like '%Saturday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -2, @to)/7-datediff(day, -1, @from)/7)
if (@param like '%Sunday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -1, @to)/7-datediff(day, 0, @from)/7)
-- final result
select datediff(day, @from, @to)+1 - @daysToSunstract as TotalDays
现在,您需要在存储过程中包含以上逻辑。
FUNCTION选项
CREATE FUNCTION [dbo].[DAYS_BETWEEN_DATES] (@from datetime, @to datetime, @exclude NVARCHAR(150))
RETURNS INT
AS
BEGIN
declare @daysToSunstract int = 0
-- find days to substract based on @param
if (@exclude like '%Monday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -7, @to)/7-datediff(day, -6, @from)/7)
if (@exclude like '%Tuesday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -6, @to)/7-datediff(day, -5, @from)/7)
if (@exclude like '%Wednesday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -5, @to)/7-datediff(day, -4, @from)/7)
if (@exclude like '%Thursday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -4, @to)/7-datediff(day, -3, @from)/7)
if (@exclude like '%Friday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -3, @to)/7-datediff(day, -2, @from)/7)
if (@exclude like '%Saturday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -2, @to)/7-datediff(day, -1, @from)/7)
if (@exclude like '%Sunday%')
set @daysToSunstract = @daysToSunstract + (select datediff(day, -1, @to)/7-datediff(day, 0, @from)/7)
-- final result
return (select datediff(day, @from, @to)+1 - @daysToSunstract as TotalDays)
END
测试:
select [dbo].[DAYS_BETWEEN_DATES]('2018-09-29', '2018-11-29', 'Monday,Friday')
答案 1 :(得分:0)
要根据变量进行计算,可以使用递归CTE来获取该范围内的日期及其对应的工作日。
然后计算那些工作日。
DECLARE @StartDate DATE = '2018-11-04';
DECLARE @StopDate DATE = '2018-11-29';
DECLARE @WorkDays INT;
SET DATEFIRST 1; -- Monday as first weekday
DECLARE @WeekendDay1 INT = 7; -- 7: Sunday, when @@DATEFIRST = 1
DECLARE @WeekendDay2 INT = 1; -- 1: Monday, when @@DATEFIRST = 1
WITH DATES AS
(
SELECT @StartDate dt, DATEPART(weekday, @StartDate) wd
UNION ALL
SELECT DATEADD(DAY,1,dt), DATEPART(weekday, DATEADD(DAY,1,dt)) wd
FROM DATES
WHERE dt < @StopDate
)
SELECT @WorkDays = COUNT(*)
FROM DATES
WHERE wd NOT IN (@WeekendDay1, @WeekendDay2)
OPTION(MAXRECURSION 366);
SELECT @WorkDays AS WorkDays;
但是,如果您有一个包含所有日期的永久表,则可以使用该表。
SET DATEFIRST 1;
SELECT COUNT(*)
FROM Calendar
WHERE [Date] BETWEEN @StartDate AND @StopDate
AND DATEPART(weekday, [Date]) NOT IN (@WeekendDay1, @WeekendDay2);
如果该表包含假期,那么您也可以在条件中使用它。