我正在寻找一种方法来计算两个日期之间的日期,但是在工作日。这是公式,但它算是周末。
DATEDIFF(DAY,STARTDATE,ENDDATE)
SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')
以上查询dateiff的结果是29天,即周末天。但我需要通过删除星期六和星期日(8天)的星期几应该是21。 有什么建议吗?
答案 0 :(得分:2)
将它放在WHERE子句
中SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')
FROM yourtable
WHERE DATENAME(dw, StartDate) != 'Saturday'
AND DATENAME(dw, StartDate) != 'Sunday'
或者所有SELECT语句
SELECT (DATEDIFF(dd, StartDate, EndDate) + 1)-(DATEDIFF(wk, StartDate, EndDate) * 2)-(CASE WHEN DATENAME(dw, StartDate) = 'Sunday' THEN 1 ELSE 0 END)-(CASE WHEN DATENAME(dw, EndDate) = 'Saturday' THEN 1 ELSE 0 END)
答案 1 :(得分:0)
这会返回22
:
DECLARE @StartDate AS DATE = '20150601'
DECLARE @EndDate AS DATE = '20150630'
SELECT
(DATEDIFF(DAY, @StartDate, @EndDate))
-(DATEDIFF(WEEK, @StartDate, @EndDate) * 2)
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END)
阅读Jeff Moden的article以获取更多信息。
说明:
首先,(DATEDIFF(DAY, @StartDate, @EndDate))
将返回天数的差异。在这种情况下,它将是29
。现在,根据您对整天的解释,您可能希望在其结果中添加1 day
。
接着,(DATEDIFF(WEEK, @StartDate, @EndDate) * 2)
:
引用文章:
DATEDIFF
WEEK
datepart实际上并没有计算周数 计算日期范围包含日期的次数 代表星期六和星期日。更多地考虑它 简单来说,它只计算整个周期!
因此,要排除周末,您必须从第一个DATEDIFF
中减去两倍的结果。现在将是:29 - (2 *4) = 21
。
最后,这个:
-(CASE WHEN DATENAME(dw, @StartDate) = 'Sunday' THEN 1 ELSE 0 END)
-(CASE WHEN DATENAME(dw, @EndDate) = 'Saturday' THEN 1 ELSE 0 END)
删除部分周,只有在周日发生@StartDate
且周六发生@EndDate
时才会发生。
答案 2 :(得分:0)
您可以尝试递归cte:
WITH cte
AS ( SELECT CAST('2015/06/01' AS DATE) AS dt ,
DATEPART(WEEKDAY, '2015/06/01') AS wd
UNION ALL
SELECT DATEADD(d, 1, dt) AS dt ,
DATEPART(WEEKDAY, DATEADD(d, 1, dt))
FROM cte
WHERE dt < '2015/06/30'
)
SELECT COUNT(*)
FROM cte
WHERE wd NOT IN ( 7, 1 )
结果是22。 您最好添加一些每个数据库应该具有的有用日历表。填写一些大范围,然后用它来计算工作日。
答案 3 :(得分:0)
我写了一个简单的存储过程 - 不知道SP是否是你所需要的,但我认为你可以很容易地将它转换为函数,TVF,无论如何:
CREATE PROCEDURE [dbo].[BusinessdaysBetween](@DateFrom DATE, @DateTo DATE, @days INT OUTPUT)
AS
BEGIN
DECLARE @datefirst INT = @@DATEFIRST
SET DATEFIRST 1 --so week starts on monday
SET @days = 0
IF @DateFrom > @DateTo
RETURN NULL
IF @DateFrom = @DateTo
RETURN @days
WHILE @DateFrom <= @DateTo
BEGIN
IF DATEPART(WEEKDAY,@DateFrom) NOT IN (6,7) --Saturday or Sunday
BEGIN
SET @days = @days + 1
END
SET @DateFrom = DATEADD(DAY,1,@DateFrom)
END
SET DATEFIRST @datefirst --restore original setup
END
GO
在我的例子中,我称之为:
DECLARE @days INT = 0
DECLARE @datefrom DATETIME = GETDATE()
DECLARE @dateto DATETIME = DATEADD(DAY,25,GETDATE())
EXEC dbo.BusinessdaysBetween @datefrom, @dateto, @days OUTPUT
SELECT @days