通过datediff计算sql中的周日

时间:2015-06-26 07:32:09

标签: sql sql-server

我正在寻找一种方法来计算两个日期之间的日期,但是在工作日。这是公式,但它算是周末。

DATEDIFF(DAY,STARTDATE,ENDDATE) 
SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')

以上查询dateiff的结果是29天,即周末天。但我需要通过删除星期六和星期日(8天)的星期几应该是21。 有什么建议吗?

4 个答案:

答案 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