我有一组8个月左右的数据,部分是2012年和部分2013年的数据.我不确定这是不是文化的东西,但我是荷兰人,我相信数据库中的数据应该用这个标准来解释.
所以我写了两个查询,一个是常规周表达式,一个是ISO_week,这个查询看起来像这样:
SELECT datepart(ISO_WEEK,date_dtm) as date_detail,
datepart(yyyy,date_dtm) as date_year,
(sum(sum_value)/sum(user_count)) as value
FROM kpi_record
WHERE kpi_series_id = '15'
AND date_dtm > dateadd(ww,-12,'2013-02-28 00:00:00.000')
group by datepart(ISO_WEEK,date_dtm), datepart(yyyy,date_dtm)
ORDER BY datepart(yyyy,date_dtm), datepart(ISO_WEEK,date_dtm)
--
SELECT datepart(ww,date_dtm) as ww,
datepart(yyyy,date_dtm) as date_year,
(sum(sum_value)/sum(user_count)) as value
FROM kpi_record
WHERE kpi_series_id = '15'
AND date_dtm > dateadd(ww,-12,'2013-02-28 00:00:00.000')
group by datepart(yyyy,date_dtm), datepart(ww,date_dtm)
ORDER BY datepart(yyyy,date_dtm), datepart(ww,date_dtm)
Run Code Online (Sandbox Code Playgroud)
这两个查询的结果分别为:
1 2012 7,14
49 2012 7,31475409836066
50 2012 7,39261285909713
51 2012 7,47905477980666
52 2012 7,30618401206636
1 2013 7,49925705794948
2 2013 7,26598837209302
3 2013 7,24533333333333
4 2013 7,22245989304813
5 2013 6,96774193548387
6 2013 7,24523160762943
7 2013 7,14718019257221
8 2013 7,34691195795007
9 2013 7,23430962343096
Run Code Online (Sandbox Code Playgroud)
和
49 2012 7,4537037037037
50 2012 7,33109017496635
51 2012 7,4656652360515
52 2012 7,36874051593323
53 2012 7,13888888888889
1 2013 7,50515463917526
2 2013 7,33190271816881
3 2013 7,17693315858453
4 2013 7,24209378407852
5 2013 7,0201072386059
6 2013 7,19281914893617
7 2013 7,17278911564626
8 2013 7,3283378746594
9 2013 7,24733096085409
Run Code Online (Sandbox Code Playgroud)
我按此顺序提出的问题是:
谢谢你的帮助,我希望我有意义.
Gar*_*thD 10
ISO标准定义了一年中的第一周(其中周是周一至周日),其中4周或更多天属于该周(即该周的大部分时间是该年),可以简化为一年的第一周包含星期四.
DATEPART(WEEK,更简单,只是DATEFIRST从年初开始经过的周边界限(定义)的计数,始终从1开始,因此您可以连续三天获得三个不同的周数,如下所示:
SET DATEFIRST 3;
SELECT [20121231] = DATEPART(WEEK, '20121231'),
[20130101] = DATEPART(WEEK, '20130101'),
[20130102] = DATEPART(WEEK, '20130102');
Run Code Online (Sandbox Code Playgroud)
在尝试分析12周的数据时,有两个因素导致您获得14行,原因同时适用于ISO_WEEK和WEEK,您的日期范围是20121206到20130228,即使这些日期相隔12周,如果您的DATEFIRST与开始日期和结束日期的工作日不匹配,那么您的日期范围将跨越13周.
ISO_WEEK函数中的第14行是因为没有ISO_YEAR函数,在ISO标准2013年第1周开始于2012年12月31日,但是因为DATEPART(YEAR2012年它将第1周分成2行:
Year Week DaysInRow
2012 1 1
2013 1 6
Run Code Online (Sandbox Code Playgroud)
使用WEEK的第14周是因为简单的计算方法,同一周(2012年12月31日 - 2013年1月6日)也分为2,但如下
Year Week DaysInRow
2012 53 1
2013 1 6
Run Code Online (Sandbox Code Playgroud)
如果你有一个日历表,那么你应该有ISO_YEAR和ISO_WEEK列(如果你不添加它们)你很容易看到20121231是2013年第1周的报告目的,如果你没有日历表(I建议你创建一个)你可以创建自己的UDF:
CREATE FUNCTION dbo.ISO_YEAR @Date DATETIME
RETURNS INT
AS
BEGIN
DECLARE @ISOyear INT = DATEPART(YEAR, @Date);
-- Special cases: Jan 1-3 may belong to the previous year
IF (DATEPART(MONTH, @DATE) = 1 AND DATEPART(ISO_WEEK, @DATE) > 50)
SET @ISOyear = @ISOyear - 1;
-- Special case: Dec 29-31 may belong to the next year
IF (DATEPART(MONTH, @DATE) = 12 AND DATEPART(ISO_WEEK, @DATE) < 45)
SET @ISOyear = @ISOyear + 1;
RETURN @ISOYear;
END
Run Code Online (Sandbox Code Playgroud)