我正在寻找一个等同于DATEPART(WEEK, @date)
的SQL Server UDF,但允许调用者指定一周的第一天。有点类似于MySql的WEEK
函数。 E.g:
CREATE FUNCTION Week (@date date, @firstdayofweek int)
RETURNS int
BEGIN
-- return result would be the same as:
-- SET DATEFIRST @firstdayofweek
-- DATEPART(WEEK, @date)
END
我的申请没有机会致电SET DATEFIRST
。
示例:
SELECT Week('2013-08-28', 2) -- returns 35
SELECT Week('2013-08-28', 3) -- returns 36
无论SQL Server的@@DATEFIRST
值如何,上述结果都将始终相同。
答案 0 :(得分:0)
您可以使用以下内容:
DATEPART(WEEK, DATEADD(DAY, 8 - @firstdayofweek, @date))
而不是移动一周的第一天,而是移动实际日期。使用此公式,将使用MS SQL Server使用的天数相同的数值设置一周的第一天。 (星期日= 1,星期六= 7)
答案 1 :(得分:0)
我发现了一些文章帮助我回答了这个问题的答案:
Deterministic scalar function to get week of year for a date
有可能简化这个UDF,但它确实给了我正在寻找的东西:
CREATE FUNCTION Week (@date DATETIME, @dateFirst INT)
RETURNS INT
BEGIN
DECLARE @normalizedWeekOfYear INT = DATEDIFF(WEEK, DATEADD(YEAR, DATEDIFF(YEAR, 0, @date), 0), @date) + 1
DECLARE @jan1DayOfWeek INT = DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, @date), 0) + @@DATEFIRST- 7) - 1
DECLARE @dateDayOfWeek INT = DATEPART(WEEKDAY, DATEADD(DAY, @@DATEFIRST- 7, @date)) - 1
RETURN @normalizedWeekOfYear +
CASE
WHEN @jan1DayOfWeek < @dateFirst AND @dateDayOfWeek >= @dateFirst THEN 1
WHEN @jan1DayOfWeek >= @dateFirst AND @dateDayOfWeek < @dateFirst THEN -1
ELSE 0
END
END
GO
然后,执行以下语句将分别返回35和36:
SELECT dbo.Week('2013-08-28', 2)
SELECT dbo.Week('2013-08-28', 3)
答案 2 :(得分:0)
/* No matter how @@DATEFIRST is return result as weekdayName,weekdayNumber Mo 1 Tu 2 Wn 3 Th 4 Fr 5 Sa 6 Su 7 */ CREATE FUNCTION dbo.fnFixWeekday ( @currentDate date ) RETURNS INT AS BEGIN -- get DATEFIRST setting DECLARE @ds int = @@DATEFIRST -- get week day number under current DATEFIRST setting DECLARE @dow int = DATEPART(dw,@currentDate) RETURN 1+(((@dow+@ds) % 7)+5) % 7 END