2013-08-28 73 views
1

我正在查找將相當於DATEPART(WEEK, @date)的SQL Server UDF,但將允許調用方指定一週中的第一天。有點類似於MySql的WEEK函數。例如:SQL Server UDF用於獲取每週的星期幾,每週的第一天參數

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

+1

所以,如果我提交2013年8月28日和2,我應該怎麼找回? –

+0

35.如果你提交2013-08-28和3,你應該回來36. –

+0

2013-01-01和1怎麼樣?另外,1代表星期天還是星期一? –

回答

0

我發現一對夫婦的文章,幫我回答的答案得出了這個問題:

  1. Deterministic scalar function to get week of year for a date

  2. http://sqlmag.com/t-sql/datetime-calculations-part-3

簡化這個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) 
0

你可以使用這樣的事情:

DATEPART(WEEK, DATEADD(DAY, 8 - @firstdayofweek, @date)) 

而不是移動的一週的第一天,你正在移動的實際日期。使用這個公式,一週中的第一天將使用MS SQL Server使用的天數來設置相同的數值。 (星期日= 1,星期六= 7)

+0

因爲你可以跨越一週的邊界,所以轉移一天將不起作用。例如,DATEPART(WEEK,'2013-08-31')返回35(@@ DATEFIRST = 7)和DATEPART(WEEK,DATEADD(DAY,8 - 1,'2013-08'31'))返回36. –

+0

我很抱歉你的上面的例子不清楚。如果一週中的第一天是第7天,那麼DATEPART(周,日期(DAY,8-7,'2013-08-31'))將返回36,因爲您剛剛表示本週的第一天是星期六和8月31日2013年是2013年的第36個星期六。所以它能正常工作。也許你正試圖解決一個不同的問題? – jellomonkey

+0

一些額外的說明,datepart WEEK不受MS SQL Server中DATEFIRST設置的影響。我找不到任何特定的文檔,但我已經測試過它。無論一週的第一天是什麼,本週都是一樣的。此外,我曾說過,8月31日至31日是第36週六,我應該說它標誌着第36周的開始,實際上是第35週六。 – jellomonkey

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+(((@[email protected]) % 7)+5) % 7 

END 
+0

這不回答我的問題。要求是該函數必須將每週的第一天作爲參數之一。 –

相關問題