我从Calendar
开始有以下2014-01-01
表。
CREATE TABLE [dbo].[TO_BDB_NOSSCE_ISO_CALENDAR](
[ID] [int] IDENTITY(1,1) NOT NULL,
[DATE] [date] NOT NULL,
[YEAR] AS (datepart(year,[DATE])) PERSISTED,
[SEMESTER] AS (case when datepart(month,[DATE])<(7) then '1' else '2' end) PERSISTED NOT NULL,
[TRIMESTER] AS (case when datepart(month,[DATE])<(4) then '1' else case when datepart(month,[DATE])<(7) then '2' else case when datepart(month,[DATE])<(10) then '3' else '4' end end end) PERSISTED NOT NULL,
[MONTH] AS (case when len(CONVERT([varchar](2),datepart(month,[DATE]),(0)))=(1) then '0'+CONVERT([varchar](2),datepart(month,[DATE]),(0)) else CONVERT([varchar](2),datepart(month,[DATE]),(0)) end) PERSISTED,
[WEEK] AS (case when len(CONVERT([varchar](2),datepart(iso_week,[DATE]),(0)))=(1) then '0'+CONVERT([varchar](2),datepart(iso_week,[DATE]),(0)) else CONVERT([varchar](2),datepart(iso_week,[DATE]),(0)) end),
[DAY] AS (case when len(CONVERT([varchar](2),datepart(day,[DATE]),(0)))=(1) then '0'+CONVERT([varchar](2),datepart(day,[DATE]),(0)) else CONVERT([varchar](2),datepart(day,[DATE]),(0)) end) PERSISTED,
[WEEKNUMBER] AS (datepart(iso_week,[DATE])),
PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
我创建了一个存储过程,并将2014-01-01
添加到2020-12-31
。
PROCEDURE [dbo].[sp_INSERT_CALENDAR_DAYS_INVERVAL]
@Increment CHAR(1),
@StartDate DATETIME,
@EndDate DATETIME
AS
BEGIN
WITH cteRange (DateRange) AS (
SELECT @StartDate
UNION ALL
SELECT
CASE
WHEN @Increment = 'd' THEN DATEADD(dd, 1, DateRange)
WHEN @Increment = 'w' THEN DATEADD(ww, 1, DateRange)
WHEN @Increment = 'm' THEN DATEADD(mm, 1, DateRange)
END
FROM cteRange
WHERE DateRange <=
CASE
WHEN @Increment = 'd' THEN DATEADD(dd, -1, @EndDate)
WHEN @Increment = 'w' THEN DATEADD(ww, -1, @EndDate)
WHEN @Increment = 'm' THEN DATEADD(mm, -1, @EndDate)
END)
INSERT INTO [TO_BDB].[dbo].[TO_BDB_NOSSCE_ISO_CALENDAR] ([DATE])
SELECT DateRange
FROM cteRange
然后,我想检索绝对周编号,遵循逻辑:当前周 - 1(上周),是零周(0),我想看看12周后和6周前往将来
with absolute_weeks as (
select distinct YEAR, WEEK
from [TO_BDB].[dbo].[TO_BDB_NOSSCE_ISO_CALENDAR]
where DATEADD(week, 0, DATE) between cast(DATEADD(WEEK, -12, GETDATE()) as date)
and cast(DATEADD(WEEK, +6, GETDATE()) as date)
)
select *, (row_number() over (order by YEAR, WEEK) - 13) as relative_week
from absolute_weeks
order by YEAR, WEEK;
我得到以下结果,周数-11到+6是正确的但由于某种原因,第12周是不正确的。你能解释为什么以及如何解决?:
YEAR WEEK relative_week
----------------------
2014 01 -12
2014 43 -11
2014 44 -10
2014 45 -9
2014 46 -8
2014 47 -7
2014 48 -6
2014 49 -5
2014 50 -4
2014 51 -3
2014 52 -2
2015 01 -1
2015 02 0
2015 03 1
2015 04 2
2015 05 3
2015 06 4
2015 07 5
2015 08 6
答案 0 :(得分:2)
我认为问题在于e。克。
DATEPART(ISO_WEEK, '20141231');
实际上会返回1
- 这是正确的但会弄乱你的数据。
您可以在基表中使用ISO_Week年份的单独字段,如下所示:
ISOWEEKYEAR = YEAR(d) + CASE WHEN DATEPART(ISO_WEEK, d) = 1 AND MONTH(d) = 12 THEN 1 ELSE 0 END
答案 1 :(得分:1)
正如@KekuSemau所指出的那样,问题与2014-12-31的ISOWEEK为1有关。你可以通过在DATE订购或者YEAR,WEEK来解决这个问题;
select year,week,(row_number() over (order by min([DATE])) - 13) as relative_week
from [dbo].[TO_BDB_NOSSCE_ISO_CALENDAR]
where [DATE] between DATEADD(WEEK, -12, GETDATE()) and DATEADD(WEEK, +6, GETDATE())
group by year,week
order by min([DATE])
当“今天”在一周的开始和结束时,您可能需要对此进行测试,以确保该行为符合您的目的。
顺便说一下 - 将问题放在一起,工作代码,明确问题等方面的荣誉 - 似乎没有多少像这样:)
<强> EDIT1 强>
这是一种完全不同的方法(我认为:)
;with cteNumbers as (select top 20 row_number() over (order by object_id) -13 as rn from sys.objects)
select c.year,c.week,n.rn
from cteNumbers n
join [dbo].[TO_BDB_NOSSCE_ISO_CALENDAR] c on c.date = cast(dateadd(d, n.rn*7, getdate()) as date)
您仍然需要对此进行测试,以确保它在一周的开始和结束时运行您想要的内容。
希望这有帮助,
里斯