好的,所以我有一份报告进行了本周与上周的比较,我们的客户注意到他们的数据“时髦”。经过进一步调查,我们发现它没有按照 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
在任何地方使用?
当 SQL Server 首次实现
WEEK
日期/部分时,他们必须做出选择。我认为对此并没有太多的意识,除了要与当时最常见的标准保持一致 - 请记住,这是在符合标准不是首要任务的时候(否则我们不会有类似的事情timestamp
,IDENTITY
和TOP
)。他们后来补充说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
有几个当局假设一年中第一周的条件不同。有些人假设一周的第一天从第一周开始,但最常见的想法是,第一个星期四的第一周是一年中的第一周。
所以
ISO_WEEK
接受这一点,就像在 2010 年、2011 年或 2012 年一样,你可以检查ISO_WEEK
说 1 月 1 日是第 52 周或第 53 周,而WEEK
或WK
或WW
说它们是第一周。