Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
按datediff计算sql中的周天数_Sql_Sql Server - Fatal编程技术网

按datediff计算sql中的周天数

按datediff计算sql中的周天数,sql,sql-server,Sql,Sql Server,我正在寻找一种方法来计算两个日期之间的天数,但是在工作日。这是公式,但它计算周末 DATEDIFF(DAY,STARTDATE,ENDDATE) SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30') 上面查询datediff的结果是29天,这是周末。但我需要一周的天数,去掉周六和周日的8天,应该是21天。 有什么建议吗?这将返回22: 更多信息,请阅读Jeff Moden的文章 说明: 首先,DATEDIFFDAY、@StartDate、@EndD

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

DATEDIFF(DAY,STARTDATE,ENDDATE) 
SELECT DATEDIFF(DAY,'2015/06/01' , '2015/06/30')
上面查询datediff的结果是29天,这是周末。但我需要一周的天数,去掉周六和周日的8天,应该是21天。 有什么建议吗?

这将返回22:

更多信息,请阅读Jeff Moden的文章

说明:

首先,DATEDIFFDAY、@StartDate、@EndDate将返回天数的差异。在这种情况下,将是29。现在,根据您对全天的理解,您可能希望在结果中添加1天

接下来,DATEDIFFWEEK、@StartDate、@EndDate*2:

引用这篇文章:

周datepart的DATEDIFF实际上并不计算周,而是 计算日期范围包含以下日期的次数: 代表成对的周六和周日。多想想 简单来说,它只计算整个周末

因此,要排除周末,必须从第一个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发生在星期六时才会发生。将其放入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)

您可以尝试递归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。
您最好添加一些每个数据库都应该具有的有用的日历表。用一些大范围填充它,然后用它来计算工作日。

我编写了一个简单的存储过程-不知道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

SQL server的哪个版本?在复制和粘贴之前,请至少在此编辑答案it@Matt,我不是从那个答案中抄来的。请参阅我的参考文章。也许我们有相同的参考资料。请注意,我从第一个DATEDIFF中删除了+1。由于您不能使用SET命令,因此您需要在函数中检查@DATEFIRST,但我认为目前为止,在数据库和服务器上只使用了两种情况@@DATEFIRST=1周从周一开始,或@DATEFIRST=7周从周日开始。只需检查数据库中@DATEFIRST的值……您可能需要使用DATENAME,因为它不依赖@DATEFIRST。谢谢@wewesthemenance,但我认为DATENAME依赖于语言!?现在我不确定了,=显然,日期名称取决于语言。试试法语。
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