仅将周数应用于整周的日期

Roy*_*mir 1 t-sql sql-server datetime sql-server-2005

现在的时间是: (m/d/yyyy) => 2009/01/04

在此输入图像描述

使用此命令,using datepart(wk,'20090104')我可以获得周数(对于任何给定的日期).

所以:

SELECT datepart(wk,'20090101') //1
SELECT datepart(wk,'20090102') //1
SELECT datepart(wk,'20090103') //1
SELECT datepart(wk,'20090104') //2
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.

问题 :

这3个第一个日期不是整周的一部分,所以我不能把它们放在一个固定的52周图表中.

我们公司需要看到关于每个信息周中52周一年.(每年有52整周).

在此输入图像描述

所以20090101不属于2009年的第一周!

它属于前一年(与我的问题无关)

所以我需要一个UDF(我一直在搜索,并ISOWEEK没有回答我的需求),这datetime给了我Week Number(周=整周,因此不考虑部分周).

示例:

calcweekNum ('20090101') //52 ...from the last year
calcweekNum ('20090102') //52 ...from the last year
calcweekNum ('20090103') //52 ...from the last year
calcweekNum ('20090104') //1
..
..
calcweekNum ('20090110') //1
calcweekNum ('20090111') //2
calcweekNum ('20090112') //2
...
Run Code Online (Sandbox Code Playgroud)

Aar*_*and 5

这是一种不同的方法.您需要提供的只是年份:

DECLARE @year INT = 2009;


DECLARE @start SMALLDATETIME;
SET @start = DATEADD(YEAR, @year-1900, 0);

;WITH n AS
(
  SELECT TOP (366) -- in case of leap year
      d = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, @start)
    FROM sys.all_objects
),
x AS 
(
  SELECT md = MIN(d) FROM n 
    WHERE DATEPART(WEEKDAY, d) = 1 -- assuming DATEFIRST is Sunday
),
y(d,wk) AS
(
  SELECT n.d, ((DATEPART(DAYOFYEAR, n.d) - DATEDIFF(DAY, @start, x.md)-1)/7) + 1
  FROM n CROSS JOIN x
  WHERE n.d >= x.md
  AND n.d < DATEADD(YEAR, 1, @start)
)
SELECT [date] = d, [week] = wk
FROM y WHERE wk < 53
ORDER BY [date];
Run Code Online (Sandbox Code Playgroud)

结果:

date        week
----------  ----
2009-01-04  1
2009-01-05  1
2009-01-06  1
2009-01-07  1
2009-01-08  1
2009-01-09  1
2009-01-10  1
2009-01-11  2
2009-01-12  2
...
2009-12-25  51
2009-12-26  51
2009-12-27  52
2009-12-28  52
2009-12-29  52
2009-12-30  52
2009-12-31  52
Run Code Online (Sandbox Code Playgroud)

请注意,第52周不一定是整周,并且在某些情况下(例如2012年),一年中的最后一天或两年可能会在第53周下降,因此它们被排除在外.

另一种方法是重复MIN表达式两次:

DECLARE @year INT = 2009;


DECLARE @start SMALLDATETIME;
SET @start = DATEADD(YEAR, @year-1900, 0);

;WITH n AS
(
  SELECT TOP (366) -- in case of leap year
      d = DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, @start)
    FROM sys.all_objects
),
y(d,wk) AS
(
  SELECT n.d, ((DATEPART(DAYOFYEAR, n.d) - DATEDIFF(DAY, @start, (SELECT MIN(d) 
    FROM n WHERE DATEPART(WEEKDAY, d) = 1))-1)/7) + 1
  FROM n
  WHERE n.d >= (SELECT md = MIN(d) FROM n WHERE DATEPART(WEEKDAY, d) = 1)
  AND n.d < DATEADD(YEAR, 1, @start)
)
SELECT [date] = d, [week] = wk
FROM y WHERE wk < 53
ORDER BY d;
Run Code Online (Sandbox Code Playgroud)