当前位置: 首页 > 面试题库 >

TSQL中日期范围内的工作日数

蒋岳
2023-03-14
问题内容

这比看起来难。我需要一个函数来计算日期范围内给定工作日的数量。我不需要任何循环或递归SQL。数以百万计的示例就是这样做的。我需要一个快速函数来进行计算。

该函数的输入将是工作日,fromdata,迄今为止

-- counting fridays
set datefirst 1
SELECT dbo.f_countweekdays(5, '2011-07-01', '2011-07-31'),
dbo.f_countweekdays(5, '2011-07-08', '2011-07-15'),
dbo.f_countweekdays(5, '2011-07-09', '2011-07-15'),
dbo.f_countweekdays(5, '2011-07-09', '2011-07-14')

预期结果:

5, 2, 1, 0

问题答案:

@Mikael Eriksson有一个绝妙的主意,但是他的实现似乎有些复杂。

这是我想出的(我想强调一下, 它基于
@Mikael

解决方案 ,主要功劳应该
归于
解决方案 ):

ALTER FUNCTION dbo.f_countweekdays (@Dow int, @StartDate datetime, @EndDate datetime)
RETURNS int
AS BEGIN
  RETURN (
    SELECT
      DATEDIFF(wk, @StartDate, @EndDate)
      - CASE WHEN DATEPART(dw, @StartDate) > @Dow THEN 1 ELSE 0 END
      - CASE WHEN DATEPART(dw, @EndDate)   < @Dow THEN 1 ELSE 0 END
      + 1
  )
END

更新

正如Mikael在其答案的注释线程中正确指出的那样,为了使上述解决方案正确运行,必须将DATEFIRST设置设置为7(Sunday)。尽管我找不到此文档,但快速测试发现它DATEDIFF(wk)忽略了实际的DATEFIRST设置,实际上返回了以周为单位的差值,就好像DATEFIRST始终设置为7。同时DATEPART(dw)尊重了DATEFIRST,因此DATEFIRST设置为other值两个函数返回的结果不一致。

因此,必须修改上述脚本,以便在计算时考虑DATEFIRST设置的不同值DATEDIFF(wk)。令人高兴的是,修复似乎并没有取得该解决方案
比以前复杂,在我看来。不过,请自行判断:

ALTER FUNCTION dbo.f_countweekdays (@Dow int, @StartDate datetime, @EndDate datetime)
RETURNS int
AS BEGIN
  RETURN (
    SELECT
      DATEDIFF(wk, DATEADD(DAY, -@@DATEFIRST, @StartDate),
                   DATEADD(DAY, -@@DATEFIRST, @EndDate))
      - CASE WHEN DATEPART(dw, @StartDate) > @Dow THEN 1 ELSE 0 END
      - CASE WHEN DATEPART(dw, @EndDate)   < @Dow THEN 1 ELSE 0 END
      + 1
  )
END

编辑: 这两个-@@DATEFIRST % 7条目都简化为just
-@@DATEFIRST,正如有人在这里建议的那样。



 类似资料:
  • 我正在尝试添加一个带有日期范围筛选器的服务器端datatable实现。筛选器不筛选任何数据。我不知道它坏在哪里。需要你帮我弄清楚我错在哪里。 这是剧本。 这是Html

  • 问题内容: 我有一个表,例如此数据 我想有一个查询,将日期分开,所以我有像这样一年中分开的金额: 2013年有25个月是因为2013年有1个月,而2014年有75个月是因为有3个月 有没有办法在T-SQL中做到这一点? 提前谢谢! 问题答案: 使用表格创建日历表格,然后将其加入表格以将日期范围划分为所需的任何部分。 如果按年份除以金额,然后除以月份,您可以: 这是SQL FIDDLE DEMO。

  • 问题内容: 我需要填充一个表,该表将存储2个给定日期之间的日期范围:09/01/11-10/10/11 因此,在这种情况下,该表将从2011年9月1日开始存储,直到每天存储到10/10/11,我想知道在SQL Server中是否有一种巧妙的方法-我目前正在使用SQL Server 2008 。 谢谢 问题答案: 在SQL 2005+上很容易;如果您有数字表或理货表,操作会更容易。我在下面伪造了它:

  • 问题内容: 假设我有个约会2013年6月20日 如何获取上周的日期范围,即本例中的6月9日至6月15日。 另外,如果日期是2013年6月2日 范围应该是5月26日至6月1日 问题答案: 这是基于Java日历的解决方案 输出 它已本地化,在我的“语言环境”周中,从星期一开始

  • 问题内容: 我有一个带有卖单的表格,我想列出两个日期之间每天的卖单数量,并且不留日期间隔。 这是我目前所拥有的: 我得到的结果如下: 但是我想要得到的是: 那可能吗? 问题答案: 动态创建日期范围并针对您的订单表进行合并:- 这可以处理多达1000天的日期范围。 请注意,根据您用于日期的字段类型,可以轻松提高效率。 编辑-根据要求,以获取每月的订单数:-

  • > 每个对象表示一个重复发生的事件。该事件可以在多个日期发生。因此,请考虑以下内容: 我有一个日历在客户端,用户可以选择一个日期范围。 > 对所选日期范围的每个条目进行调用,并在客户端处理聚合。问题是会有大量的读取,因为我们会多次读取重叠的日期范围内的同一个列表对象。 尝试使用类似ElasticSearch/Algolia的服务来完成此操作 任何建议都会很有帮助!