DATEFIRST 的影响力
DATEFIRST 用来确定一周中第一天是星期几。可以通过 SET DATEFIRST 和 @@DATEFIRST 来设置和返回其值:
值 | 一周的第一天是 |
1 | 星期一 |
2 | 星期二 |
3 | 星期三 |
4 | 星期四 |
5 | 星期五 |
6 | 星期六 |
7 (默认值,美国英语) | 星期日 |
DATEFIRST 主要影响日期函数中涉及到星期的两个参数: WEEK 和 WEEKDAY :前者通常表示指定日期是当年的第几个星期;后者通常表示指定日期是一周中第几天。
所有的日期函数中,只有 DATEPART 函数受 DATEFIRST 的影响,其它函数都不受其影响。 下面来详细说说。
1. DATEPART 受其影响
DATEPART(WEEKDAY, @DT) 返回指定日期是一周中的第几天,注意是相对于 DATEFIRST 为一周中第一天,这和是星期几不是一个概念。这也就是说,随着 DATEFIRST 设置不同,同一日期的上述返回值也不同。为了抵消这种影响,我们可以将 @@DATEFIRST 添加到 @DT 上,此时调用 DATEPART 与把 DATEFIRST 设为 7 的结果是一致的。如果你想把 DATEFIRST 逻辑 地设置为 n ,从日期减去常数 n 即可:
DATEPART(WEEKDAY, @DT + @@DATEFRST - n)
DATEPART(WEEK, @DT) 返回指定日期是一年中第几个星期。用下面这种方法表述也许能更好理解这个函数: SQL Server 总是将每年的 1 月 1 日 所在的 WEEK 的值总是 1 ,其后每经过一个 DATEFIRST 就将值增加 1 。
很多查询中要求按周分组,此时我们可以设置好 DATEFIRST (因为中国人习惯是星期一是一周的第一天,而 SQL SERVER 缺省却是星期日是第一天),然后调用 DATEPART(WEEK, @DT) 分组就可以了。如果你想只是把 DATEFIRST 逻辑 地设置为 n ,那可调用如下:
DATEPART(WEEK, @DT + @@DATEFRST - n)
2. DATEDIFF 不受影响
DATEDIFF(WEEKDAY, @DT1, @DT2) 和 DATEDIFF(DAY, @DT1, @DT2) 返回的结果一致。
DATEDIFF(WEEK, @DT1, @DT2) 则和 DATEFIRST 为 7 时的 DATEPART(WEEK, @DT2) – DATEPART(WEEK, @DT1) 一致。
3. DATENAME 不受影响
DATENAME(WEEKDAY, @DT) 返回当前语言中,指定日期是星期几的字符串,比如下表分别为中(简体中文)英( us_english )文下的返回值(不包括引号):
简体中文 | us_english |
“星期一” | “ Monday ” |
“星期二” | “ Tuesday ” |
“星期三” | “ Wednesday ” |
“星期四” | “ Thursday ” |
“星期五” | “ Friday ” |
“星期六” | “ Saturday ” |
“星期日” | “ Sunday ” |
DATENAME(WEEK, @DT) 则返回的 DATEFIRST 为 7 时的 DATEPART(WEEK, @DT) 的值。
4. DATEADD 不受影响
DATEADD(WEEKDAY, n, @DT) 相当于 DATEADD(DAY, n, @DT)
DATEADD(WEEK, n, @DT) 相当于 DATEADD(DAY, n * 7, @DT) 即 n 个星期以后的日期是多少。
参考书籍:
1 .《 Microsoft SQL Server2005 技术内幕: T-SQL 程序设计》