Некоторые функции можно выполнить с помощью функций datetime, чтобы вычислить дату только из номера недели и номера дня недели.
Однако помните, что @@DATEFIRST
может отличаться на сервере.
Который определяет, какой день недели является первым днем недели.
Поэтому лучше всего изменить его в своем сеансе на 1, чтобы понедельник стал первым рабочим днем.
Без этого может потребоваться корректировка в приведенном ниже расчете.
Например, [Weekday]+1
, когда select @@DATEFIRST
возвращает 7
.
Пример фрагмента:
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;