【问题标题】:Subtract Business Days Using Date Dimension Calendar使用日期维度日历减去工作日
【发布时间】:2021-05-26 04:32:08
【问题描述】:

许多 cmets 建议在 SQL Server 中创建一个日期表来计算工作日和假日 - 好主意!我找到了一篇很棒的如何在 SQL Server 中创建这样一组表的方法文章 - https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/。如果您需要进行大量日期计算,我强烈推荐这篇文章。

根据这些表,我创建了一个名为 USCalendar 的视图,它计算结束日期,给定开始日期 (03/01/21) 和工作日数 (180) - 完美运行!

select Top 1 TheDate as EndDate
from (
    select Top 180 TheDate from USCalendar
    Where TheDate>='03/01/2021'
    And IsWeekend=0 and IsHoliday=0
    Order By TheDate
) as BusinessDays
Order By TheDate DESC

我唯一的挑战是想出一种方法来扭转它 - 如果我知道目标结束日期和工作日数,我如何找到开始日期?

【问题讨论】:

  • 您可以简单地在您的表格中添加一个序列号,该序列号在每个“工作日”递增(在非工作日重复)。然后,您只需找到该值与您的开始日期相差 100 的行(在任一方向上)。归功于 Joe Celko 的这个想法。请注意,“工作日”并不总是与“工作日”相同,原因有多种 - 自然灾害、强制关闭、假期等。了解您的要求。

标签: sql sql-server tsql datetime


【解决方案1】:

如果您只想要一次约会,实际上并不需要所有这些。

你可以这样做

select TheDate as EndDate
from USCalendar
Where TheDate >= '03/01/2021'
  And IsWeekend = 0 and IsHoliday = 0
Order By TheDate
OFFSET 179 ROWS
FETCH NEXT 1 ROW ONLY;

为了扭转这种情况,我们将其更改为<= 并按另一个方向排序:

select TheDate as EndDate
from USCalendar
Where TheDate <= '03/01/2021'
  And IsWeekend = 0 and IsHoliday = 0
Order By TheDate DESC
OFFSET 179 ROWS
FETCH NEXT 1 ROW ONLY;

我建议你把它做成一个内联的表值函数,这样你就可以把任何日期放进去。它基本上变成了一个参数化的视图。它被内联到外部查询中,因此非常高效:

CREATE /* OR ALTER */ FUNCTION dbo.GetBusinessEndDate
( @StartDate date, @numberOfDays int )
RETURNS TABLE
WITH SCHEMABINDING
AS RETURN (
    select TheDate as EndDate
    from USCalendar
    Where TheDate >= @StartDate
      And IsWeekend = 0 and IsHoliday = 0
    Order By TheDate
    OFFSET @numberOfDays ROWS
    FETCH NEXT 1 ROW ONLY
);

您可以像使用任何其他表格或视图一样使用它,也可以CROSS APPLY 它。

我建议为StartDate 制作一个单独函数,不要尝试组合它。

【讨论】:

  • 太棒了——这正是我想要的!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-08-31
  • 1970-01-01
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多