【问题标题】:SQL Server : how do you exclude weekends using datediff?SQL Server:如何使用 datediff 排除周末?
【发布时间】:2018-03-26 18:05:26
【问题描述】:

我还在学习 SQL,所以请记住这一点。我有一个查询返回特定范围的平均天数,尽管我的范围不考虑周末和节假日。假期可能有点棘手,但我如何将周末排除在我的范围之外?

例如,我有一个 02-01-18 到 02-15-18 的范围,其中 datediff 是 14 天,但是我如何让 SQL 识别该范围内的哪些天是周末以及是否要将它们排除在外我的日期差异?

我的查询是

SELECT
    AVG(1.00 * DATEDIFF(DAY, xx, yy)) AS DayDiff
FROM 
    datebase1.dbo.table1
WHERE
    MONTH(datecompleted) = MONTH(DATEADD(month, -1, current_timestamp))
    AND YEAR(datecompleted) = YEAR(DATEADD(month, -1, current_timestamp))
    AND ApprovalRequiredFrom = 'pp'

我确实有一个可以提供的日历,它告诉我日期和当天的名称,但我想避免这样做。我希望能够将周末排除在我的范围之外,以获得更准确的结果。

谢谢

【问题讨论】:

  • 之前有人问过这个问题:stackoverflow.com/questions/7388420/…
  • 我已经阅读了这两个问题,我需要一些关于 WHERE ((DATEPART(dw, xx, yy) + @@DATEFIRST) % 7) NOT IN (0, 1) 正确语法的帮助)?
  • 我使用 DimDate 维度执行此操作,并将其用于您的日期工作。如果您有每日粒度,那么它将是 (Select Count(*) from DimDate where DateVal between xx and yy and DayOfWeek not in (1,7)
  • 不确定如何让它正常工作

标签: sql-server ssms datediff


【解决方案1】:

要排除周末,您需要从比较日期(xxyy)中过滤周六和周日。为此,您可以使用带有WEEKDAY 参数的DATEPART 函数。结果是一个从 1 到 7 的数字,表示它是星期几。

-- 2018-01-01 is a monday
SELECT DATEPART(WEEKDAY, '2018-01-01')
-- Result: 2

问题在于不同的数据库配置与值“1”相关的日期发生了变化,因此可能星期几“1”对某些人来说意味着星期日,而对另一些人来说意味着星期一。为了统一这一点,您可以使用SET DATEFIRST 更改默认值。

SET DATEFIRST 1 -- 1: Monday, 7: Sunday

-- 2018-01-01 is a monday
SELECT DATEPART(WEEKDAY, '2018-01-01')
-- Result: 1

另一个与 datefirst 无关的解决方案是直接在表达式上使用 @@DATEFIRST 会话值。 @@DATEFIRST 保存我们在 SET DATEFIRST 语句中设置的值,或数据库默认值。请注意,结果是一样的,即使更改DATEFIRST

SET DATEFIRST 7 -- 1: Sunday, 2: Monday

-- 2018-01-01 is a monday
SELECT (DATEPART(WEEKDAY, '2018-01-01') + @@DATEFIRST) % 7
-- Result: 2


SET DATEFIRST 1 -- 1: Monday, 7: Sunday

-- 2018-01-01 is a monday
SELECT (DATEPART(WEEKDAY, '2018-01-01') + @@DATEFIRST) % 7
-- Result: 2

对于您的示例,您需要过滤 xxyy 日期而不是周末。将以下内容添加到您的 WHERE 子句中:

WHERE
    --...
    AND (DATEPART(WEEKDAY, xx) + @@DATEFIRST) % 7 NOT IN (0, 1)
    AND (DATEPART(WEEKDAY, yy) + @@DATEFIRST) % 7 NOT IN (0, 1)

【讨论】:

    【解决方案2】:

    因为需要使用旧的 MySQL 5.1 服务器,所以有机会尝试一种“数学”方式来计算否。 SAT / SUN 减去:

    注意:MySQL 的“weekday”函数返回 0 表示周一,5 表示 SAT,6 表示 SUN,因此您在下面看到 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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-15
      • 2010-12-20
      • 2015-08-17
      • 1970-01-01
      • 2015-02-13
      • 1970-01-01
      • 2019-02-04
      • 1970-01-01
      相关资源
      最近更新 更多