Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于周数和日数字段设置SQL日期字段值_Sql_Sql Server_Date Arithmetic - Fatal编程技术网

基于周数和日数字段设置SQL日期字段值

基于周数和日数字段设置SQL日期字段值,sql,sql-server,date-arithmetic,Sql,Sql Server,Date Arithmetic,是否有基于周值和日值设置日期值的程序或方法 要使用此日历年进一步详细说明: 1月1日至7日是第1周, 1月8日至14日为第2周等 至于天数值; 星期一是1点 星期二是2点 星期三是3点 星期四是4点 星期五是5点 使用此逻辑,我希望创建并填充一个使用这些值的日期字段 例如,我希望Week:2-Day:3将我的新日期字段填充为2018年10月1日 任何帮助和指导都将不胜感激 您可以参考此链接,该链接包含日历表创建语句 您需要做的是将可用列(如年、周和日)映射到日历表,并提取日期也许类似的内容可以

是否有基于周值和日值设置日期值的程序或方法

要使用此日历年进一步详细说明: 1月1日至7日是第1周, 1月8日至14日为第2周等

至于天数值; 星期一是1点 星期二是2点 星期三是3点 星期四是4点 星期五是5点

使用此逻辑,我希望创建并填充一个使用这些值的日期字段

例如,我希望Week:2-Day:3将我的新日期字段填充为2018年10月1日


任何帮助和指导都将不胜感激

您可以参考此链接,该链接包含日历表创建语句


您需要做的是将可用列(如年、周和日)映射到日历表,并提取日期

也许类似的内容可以帮助您开始。 它将返回您的样本日期,但我没有在所有情况下测试。。。 因此,我确信它需要一些微调,使用@Ajan Balakumaran建议的日历表会更好

declare @year int = datepart(year, getdate())
declare @month int
declare @week int = 2
declare @day int = 3

SELECT @month = DATEPART(MM,CAST(CONVERT(CHAR(3),
                         DATEADD(WW, @WEEK - 1,
                         CONVERT(datetime, '01/01/' + CONVERT(char(4) ,@Year)))
                         , 100) + ' 1900' AS DATETIME))

select datefromparts(2018, @month, @day + (@week - 1) * 7)

使用datetime函数可以完成一些操作,仅根据周数和工作日数计算日期

但是,请注意@@DATEFIRST在服务器上可能不同。 它定义了哪一个工作日是一周中的第一天。 因此,最好在会话中将其改为1,使星期一成为第一个工作日。 如果没有它,可能需要在下面使用的计算中进行调整。 例如,选择@@DATEFIRST时[Weekday]+1返回7

示例代码段:

结果:

请注意,年份基于当前日期

但是如果是更新现有的表呢? 然后你可以用另一种方式来看待它。 创建一个包含当前年份中所有日期的临时表,并从这些日期派生周和工作日。 然后可以使用该临时表更新现有表

示例代码段:


这很有效。非常感谢。我发现很难理解的是,如何使用同一行中的weekno和dayno字段来更新另一个具有空白CalcDate字段的表。@Potatocucker只需了解如何正常更新表,并使用计算即可。如:updateyourtable set yourfield=其中yourfield为空。但如果是一次性更新,我会硬编码年份,而不是从GetDate开始计算。@Potatocucker我稍微调整了计算。谢谢你的洞察力和帮助。我已经实现了你的代码,并在我这边进行了测试,但我有一个问题,我需要这超出一年的范围。我有一个记录年份值“2018”、“2019”等的字段。这是否可以用作设置总日期的手段,而不必声明每个给定年份并将其插入tmpDates?或者有没有办法在tmp日期中插入多年?再次感谢@Potatocucker你应该仔细看看表中的第二个解决方案。您可以为startDate和endDate设置变量,然后只使用SQL for tmpdate中的变量。并将DATE2018 CTE重命名为just DATES。因为2017年的日期听起来是错误的;p并将MAXRECURSION设置为更高或0。实际上,它可以作为一个永久表,而不是临时表,并带有额外的日期相关字段。使其可用于其他查询,通常是命名为Calendar的查询。
declare @Table table ([Week] int, [Weekday] int);

insert into @Table ([Week], [Weekday]) values
 (1, 1)
,(1, 7)
,(2, 1)
,(2, 7)
;

-- The US default for @@DATEFIRST is 7, which would make Sunday weekday 1. 
-- By setting @@DATEFIRST to 1 then Monday will be weekday 1
SET DATEFIRST 1; 

SELECT [Week], [Weekday],
DATEADD(WEEKDAY, 1-DATEPART(WEEKDAY, DATEFROMPARTS(DATEPART(YEAR,GetDate()),1,1)), DATEADD(WEEK,[Week]-1, DATEFROMPARTS(DATEPART(YEAR,GetDate()),1,[Weekday]))) AS CalcDate
FROM @Table
ORDER BY [Week], [Weekday];
Week Weekday CalcDate
---- ------- ----------
   1       1 2018-01-01
   1       7 2018-01-07
   2       1 2018-01-08
   2       7 2018-01-14
-- Create a temporary table
IF OBJECT_ID('tempdb..#tmpDates') IS NOT NULL DROP TABLE #tmpDates;
CREATE TABLE #tmpDates ([Week] INT NOT NULL, [WeekDay] INT NOT NULL, [Date] DATE NOT NULL, PRIMARY KEY ([Week], [WeekDay]));

-- Make Monday the first weekday
SET DATEFIRST 1;

-- Filling the temp table with data
WITH DATES2018 AS
(
  SELECT CAST('2018-01-01' AS DATE) AS [Date]
  UNION ALL
  SELECT DATEADD(day, 1, [Date])
  FROM DATES2018
  WHERE [Date] < CAST('2018-12-31' AS DATE)
)
INSERT INTO #tmpDates ([Date], [Week], [WeekDay])
SELECT [Date], DATEPART(WEEK, [Date]) AS [Week], DATEPART(WEEKDAY, [Date]) as [WeekDay]
FROM DATES2018
ORDER BY [Week], [WeekDay]
OPTION (MAXRECURSION 366);


-- Just using a table variable per demonstration
declare @YourTable table ([Week] int, [Weekday] int, [Date] DATE);
-- Sample data
insert into @YourTable ([Week], [Weekday]) values
 (1, 1)
,(1, 7)
,(2, 1)
,(2, 7)
;

-- update based on the temp table
update t
set [Date] = tmp.[Date]
from @YourTable t 
join #tmpDates tmp on (tmp.[Week] = t.[Week] AND tmp.[WeekDay] = t.[Weekday])
where (t.[Date] is null OR t.[Date] <> tmp.[Date]);

select * from @YourTable;