SQL Server:使用参数获取日期年、周、工作日

SQL Server:使用参数获取日期年、周、工作日,sql,sql-server,sql-server-2008,date,Sql,Sql Server,Sql Server 2008,Date,我已经搜索过了,还没有找到这个有用的小片段 我想输入 年份(2014年) 周数(2) 工作日(2=周二,在我的情况下) 预期结果:2014-01-07(1月7日) 还有谁能得到完整的日期作为回报 编辑:我的服务器是SQL 2008 完成的代码感谢大家 declare @year int = 2014 declare @weeknr int = 2 declare @daynroffset int = 2 SELECT DATEADD(DAY,+ (@daynroffset-1),

我已经搜索过了,还没有找到这个有用的小片段

我想输入

  • 年份(2014年)
  • 周数(2)
  • 工作日(2=周二,在我的情况下)
预期结果:
2014-01-07
(1月7日)

还有谁能得到完整的日期作为回报

编辑:我的服务器是SQL 2008


完成的代码感谢大家

declare @year int = 2014
declare @weeknr int = 2
declare @daynroffset int = 2


SELECT 
  DATEADD(DAY,+ (@daynroffset-1),
    DATEADD(DAY,-DATEPART(DW,CAST('1/1/' + cast(@year as varchar) AS Date))+2,DATEADD(WK,@weeknr-    1,CAST('1/1/' + cast(@year as varchar) AS Date)))
  )

这可能会在年份边界附近出现问题,但它适用于给定的示例数据。您可能需要添加进一步的验证。我已经将datetime操作的每一步分解为一个新字段,这样您就可以看到它正在被构造

2008年

2012年+

代码: 2012+:
DATEADD(DAY,-DATEPART(DW,DATEFROMPARTS(“年”,1,1))+1+“周中的一天”,DATEADD(WK,“周数”-1,DATEFROMPARTS(2014,1,1)))

2008+:

只需在必要时替换这些值

这适用于任何日期。

其他答案(到目前为止)使用SQL Server默认机制来确定星期和星期几。在这种情况下,当前语言设置确定一周中的哪一天(通过
@@DATEFIRST
设置),而
DATEPART(wk
使用1月1日作为第一周中包含的固定日期

declare @year int = 2014
declare @week int = 2
declare @day int = 2

declare @date datetime = cast(cast(@year as varchar(20)) + '-01-01' as datetime)
declare @offset int = datepart(dw, @date) - 1
set @date = dateadd(day, @day - @offset, dateadd(ww, @week - 1, @date))

print @date
要获得独立于语言设置的确定性答案,可以使用从周一开始的一周,其中第一周始终包含1月4日

此代码根据ISO周数确定日期:

declare @year int = 2016
declare @isoweek int = 22
declare @isoday int = 2

-- ISO-WEEK 1 always contains 4th Jan, so let's use this as a base
declare @date datetime = cast(cast(@year as varchar(4)) + '-01-04T12:00:00' as datetime)

-- Offset the wanted DayOfWeek versus our base date
-- We also set DATEFIRST temporarily because it affects DayOfWeek
-- ISO-Weeks always start on Monday
declare @datefirst int = @@DATEFIRST
SET DATEFIRST 1
declare @offset int = datepart(dw, @date) - 1
SET DATEFIRST @datefirst

-- Add given day and week to basedate
set @date = dateadd(day, @isoday - 1 - @offset, dateadd(wk, @isoweek - 1, @date))

print @date

您需要一个日历表请参见SQL Server 2012及更新版本function@bummi,marc_的回答很好,但不是针对这个问题。@AndreyDavydenko:计算周数的方法没有很好的定义。但是有一个ISO标准,SQL Server默认情况下不使用该标准。如果要使用ISO周数,可以通过在上使用该标准来添加校正系数上面计算的日期:
declare@isowk\u offset int=datepart(WK,@date)-datepart(isowk,@date)set@date=DATEADD(WK,@isowk\u offset,@date)
。不过,这可能还不足以应对年度变化。(第1周与第52或53周).很好…但是不要认为2008年的datefromparts是函数那么你可以在一个
CAST
中替换一个
CONCAT
。是的…除了缺少的CONCAT函数之外…认为我有它…使用了“+”请签名,谢谢你让我上路……我会把结果贴出来的here@freand,检查我的更新答案。应该是您需要的。SQL 2008在2016年的结果不正确。例如,输入数据:y=2016,w=22,d=2。应该是2016-05-31,但结果是2016-05-24。请有人解释并提供更正的代码。不适用于SQL Server 2008。
DATEFROMPARTS
出现在2012年。不适用于SQL Server 2008。
DATEFROMPARTS
出现在2012年。只需添加一件事-构造
cast(cast(@year as varchar(4))+'-01-04'as datetime)
取决于设置。它可能不是1月4日,而是4月1日。其余的都很好!@AndreyDavydenko:谢谢你的赏金!我觉得使用格式
yyyy-mm-dd
是安全的,但你是对的,不是。不过,完整的ISO 8601格式应该是安全的,所以我会相应地更新答案。TY!我使用d
CONVERT
的样式为:
CONVERT(DATETIME,CONVERT(VARCHAR(4),@year)+'0104',112)
declare @year int = 2014
declare @week int = 2
declare @day int = 2

declare @date datetime = cast(cast(@year as varchar(20)) + '-01-01' as datetime)
declare @offset int = datepart(dw, @date) - 1
set @date = dateadd(day, @day - @offset, dateadd(ww, @week - 1, @date))

print @date
declare @year int = 2016
declare @isoweek int = 22
declare @isoday int = 2

-- ISO-WEEK 1 always contains 4th Jan, so let's use this as a base
declare @date datetime = cast(cast(@year as varchar(4)) + '-01-04T12:00:00' as datetime)

-- Offset the wanted DayOfWeek versus our base date
-- We also set DATEFIRST temporarily because it affects DayOfWeek
-- ISO-Weeks always start on Monday
declare @datefirst int = @@DATEFIRST
SET DATEFIRST 1
declare @offset int = datepart(dw, @date) - 1
SET DATEFIRST @datefirst

-- Add given day and week to basedate
set @date = dateadd(day, @isoday - 1 - @offset, dateadd(wk, @isoweek - 1, @date))

print @date