好的,所以我有一个报告进行了本周与上周的比较,我们的客户注意到他们的数据“很笨拙”。经过进一步调查,我们发现按照ISO标准,它不能正确运行数周。我将此脚本作为测试用例运行。

SET DATEFIRST 1
SELECT DATEPART(WEEK, '3/26/13')
    , DATEPART(WEEK, '3/27/12')
    , DATEPART(WEEK, '3/20/12')
    , DATEPART(WEEK, '1/2/12')
SELECT DATEPART(ISO_WEEK, '3/26/13')
    , DATEPART(ISO_WEEK, '3/27/12')
    , DATEPART(ISO_WEEK, '3/20/12')
    , DATEPART(ISO_WEEK, '1/2/12')


运行时我得到了这些结果。



我认为这很特殊,因此我做了一些进一步的挖掘,发现SQL Server将1月1日视为一年的第一周,而ISO将1月的第一个星期日视为一年的第一周。

然后问题变成了两个问题。问题1这是为什么?问题2是否有任何方法可以更改此设置,因此我不必修改所有代码即可在任何地方使用ISO_Week

#1 楼

当SQL Server首次实现WEEK日期/日期时,他们不得不做出选择。除了当时符合最普遍的标准外,我认为并没有太多的意识-请记住,在那个时候符合标准并不是当务之急(否则我们不会timestampIDENTITYTOP)。他们后来添加了ISO_WEEK(我相信是2008年),因为与此同时,解决方法是编写自己的,缓慢的,糟糕的标量UDF-实际上,他们甚至创建了一个非常糟糕的标量UDF并将其放入官方文档中(此后已被删除据我所知)。

我不知道一种使DATEPART(WEEK假装为DATEPART(ISO_WEEK的方法-我认为您将不得不更改代码(如果您使用的是源代码管理,不应该很辛苦-您要在多少个位置执行此计算?您是否考虑过在某个地方进行计算,因此您的代码不必为此感到费解?因为您现在正在更改代码,这可能是时候了考虑一下...)。

如果您真的想要为什么的答案?我认为您必须吸引一些原始开发人员来确定为什么他们选择默认设置。同样,我认为这不是实际的“ F标准!”选择,而是“什么标准?”

这里有一些有用的信息:

https://stackoverflow.com/questions/348880/getting-week-number-off-a-date- in-ms-sql-server-2005

http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/iso-week-in-sql-server

评论


从技术上讲,我要做的就是更改我的DimCalendar表,不幸的是,我们的开发人员决定不在多个报表实例中使用它,因此它是即时计算的。总的来说,这更多是出于好奇,而不是任何形式的危机。

–赞恩
13年3月27日在16:06

我建议您让开发人员更新他们的报告,以遵循最佳实践,而不是牛仔编码。但这就是我。

–亚伦·伯特兰(Aaron Bertrand)
2013年3月27日16:16

好消息是不到一周的时间,他们将不再是我的开发人员。 :)

–赞恩
13年3月27日在16:21

#2 楼

有几个权威机构对一年的第一周采取不同的条件。
有些人认为一周的第一天从第一周开始,但是最常见的想法是,具有第一个星期四的第一周是该周的第一周。

因此,ISO_WEEK接受了这一点,例如在2010年,2011年或2012年,您可以检查ISO_WEEK表示1月1日是第52周或第53周,而WEEKWKWW说是第一周。

SELECT DATEPART (WW,'01/01/2010')   --> 1
SELECT DATEPART (WK,'01/01/2010')   --> 1
SELECT DATEPART (WEEK,'01/01/2010')   --> 1
SELECT DATEPART (ISO_WEEK,'01/01/2010')   --> 53