【问题标题】:How to return the correct start date value from a stored procedure in this case?在这种情况下,如何从存储过程中返回正确的开始日期值?
【发布时间】:2018-10-18 08:31:05
【问题描述】:

我正在使用以下情况条件来计算 StartDate 变量:

DECLARE @StartDate Date =
   DATEADD(DAY, CASE WHEN DATEPART(dw, GETDATE()) = 2 THEN -10 ELSE -8 END, GETDATE())

如您所见,如果今天的日期是星期一,则从今天的日期中减去 10 天,否则将减去 8 天。由于今天(2018 年 10 月 16 日)不是星期一,这将返回 10/8/2018 作为输出(扣除 8 天)。如果在星期一 (10/15) 执行,则 @StartDate 将返回 10/5 作为输出。

我添加了一个名为 Holidays 的表,它有两列 Holiday NameDate 包含今年的三条记录:哥伦布日:10/8、退伍军人节 11/12 和感恩节 11/22。

现在我要做的具有挑战性的部分是,如果 @StartDate 的返回输出是 10/8(今天执行的查询:10/16),这是一个假期(星期一),那么 @StartDate 的值应该是更改为 10/5(前一个工作日,周六和周日除外)。另外如果@StartDate的值为10/5(查询于10/15执行),则该值应改为10/4,因为10/8是假期,不计入10天的扣减所以应该是 10/4 而不是 10/5。

所以理论上它应该这样工作:检查今天日期和@StartDate之间是否有任何假期,如果有,则使用前一天并根据我上面提到的情况相应地调整星期一。

请注意,我在顶部提到的包含语句是存储过程的一部分。

我怎样才能完成这项工作,有人可以帮忙吗?提前致谢。

【问题讨论】:

  • 这只是过程的开始吗?将来您可能会一个接一个地有多个假期,还是只有一天?
  • Just use a calendar table of 所有的日子,而不仅仅是假期,并适当地标记它们。将所有这些逻辑构建到查询中,您将忽略异常(例如两天假期,周一假期),具有不同DATEFIRST 的人将运行该代码并得到错误结果等. 这个问题已经解决了;不要重新解决它。
  • 提示:( @@DateFirst + DatePart( weekday, SampleDate ) - 1 ) % 7 + 1 将始终返回一个从17 的整数,其中1 对应于星期日,无论DateFirstLanguage 的设置如何。不要指望多次调用 GetDate() 返回相同的值,捕获一次,例如declare @Today as Date = Cast( GetDate() as Date);,并使用该值。

标签: sql sql-server tsql stored-procedures


【解决方案1】:

假设您的假期中没有连续的多个日期,这将在一个(ish)语句中完成。如果您愿意,可以轻松地将其分成两部分:

DECLARE @StartDate date

;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select @StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d 
left join holiday on holiday.date=dt

编辑:这是一个完整的工作副本。我创建了一个表变量来保存假期,运行初始查询,然后将返回的日期插入为假期,然后再次运行查询。如果你在 sql server 中运行,你会看到第二个查询返回第一个查询的前一天。

declare @holiday table(date date)
DECLARE @StartDate date

;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select @StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d 
left join @holiday holiday on holiday.date=dt

select @startdate

insert @holiday values (@startdate)

;with d as (
select convert(date,dateadd(day,case when datepart(dw,getdate())=2 then -10 else -8 end,getdate())) dt
)
select @StartDate=case when holiday.date is null then dt else dateadd(day,-1,dt) end
from d 
left join @holiday holiday on holiday.date=dt

select @startdate

【讨论】:

  • 感谢 TomC。放假日期是固定的,明年会更新
  • 一年大约有10个假期,这是唯一需要计算的时间
  • 当 StartDate 的输出等于 Datatable 中提到的日期字段之一时,我们需要执行我在描述中提到的条件检查
  • 谢谢@mdevm,问题是如果连续有两个假期会发生什么。我们需要返回多天吗?
  • 不需要。只有当 StartDate 输出等于此处列出的任何联邦假日时,该场景才会出现:federalreserve.gov/aboutthefed/k8.htm
猜你喜欢
  • 2021-08-31
  • 1970-01-01
  • 2016-11-06
  • 2014-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多