如何在SQL中从当前日期获取下一个9周的数字?
如果我给出的日期为2015-12-31,则必须显示为如何在SQL中从当前日期获取下一个9周的数字?,sql,sql-server-2008,week-number,Sql,Sql Server 2008,Week Number,如果我给出的日期为2015-12-31,则必须显示为 2015W53, for 2015-12-31, which means Week 53, and next follows as 2016W1, Next as 2016W2, Next as 2016W3 Next as... 我的逻辑是 DECLARE @WEEK VARCHAR(2), @YEAR VARCHAR(4) SELECT @YEAR = DATEPART(YY,@
2015W53, for 2015-12-31, which means Week 53, and next follows as
2016W1, Next as
2016W2, Next as
2016W3 Next as...
我的逻辑是
DECLARE @WEEK VARCHAR(2), @YEAR VARCHAR(4)
SELECT @YEAR = DATEPART(YY,@DATE), @WEEK = CAST(DATEPART(WK,@DATE) AS INT) % 52 ;
IF(CAST(DATEPART(WK,@DATE) AS INT) % 52 = 0)
SET @WEEK = 52;
IF(CAST(DATEPART(WK,@DATE) AS INT) = 53)
SET @YEAR = CAST(@YEAR AS INT) + 1;
IF (LEN(@WEEK) < 2)
BEGIN
SET @WEEK = LEFT('0' + @week, 2)
END
RETURN @YEAR + @WEEK
声明@WEEK VARCHAR(2),@YEAR VARCHAR(4)
选择@YEAR=DATEPART(YY,@DATE),@WEEK=CAST(DATEPART(WK,@DATE)作为INT)%52;
如果(将日期部分(WK,@DATE)转换为INT)%52=0)
设置@WEEK=52;
如果(演员阵容(日期部分(工作周,@DATE)为整数)=53)
设置@YEAR=CAST(@YEAR为INT)+1;
如果(LEN(@周)<2)
开始
设置@WEEK=LEFT('0'+@周,2)
结束
返回@YEAR+@周
但是这里的2015W53不见了,我还有9周的时间
我也只想要今年的最后一周。。,
尝试了很多次,但都没有成功。
任何帮助都是非常感谢的。您不能将
@WEEK
设置为DATEPART(WK,@DATE)%52
,因为有些年份有52周以上!如果每年正好有52周,事情就容易了
为什么不先确定给定的@DATE
的周数,然后使用DATEADD
添加一周,看看结果如何?你这样做9次,你就会得到你想要的
例如:
DECLARE @yearsAndWeeks TABLE (Year INT, Week INT)
DECLARE @i INT
SET @i = 0
DECLARE @Date DATETIME
SET @Date = '20151231'
WHILE @i < 9
BEGIN
INSERT INTO @yearsAndWeeks (Year, Week) VALUES (DATEPART(yy, @Date), DATEPART(ISO_WEEK, @Date))
SET @Date = DATEADD(WK, 1, @Date)
SET @i = @i + 1
END
SELECT * FROM @yearsAndWeeks
DECLARE@yearsAndWeeks表(Year INT,Week INT)
声明@i INT
设置@i=0
声明@Date-DATETIME
设置@Date='20151231'
而@i<9
开始
在@yearsAndWeeks(Year,Week)值中插入日期部分(yy,Date),日期部分(ISO_Week,Date))
SET@Date=DATEADD(第1周,@Date)
设置@i=@i+1
结束
从@yearsAndWeeks中选择*
您不能将@WEEK
设置为DATEPART(WK,@DATE)%52
,因为有些年份超过52周!如果每年正好有52周,事情就容易了
为什么不先确定给定的@DATE
的周数,然后使用DATEADD
添加一周,看看结果如何?你这样做9次,你就会得到你想要的
例如:
DECLARE @yearsAndWeeks TABLE (Year INT, Week INT)
DECLARE @i INT
SET @i = 0
DECLARE @Date DATETIME
SET @Date = '20151231'
WHILE @i < 9
BEGIN
INSERT INTO @yearsAndWeeks (Year, Week) VALUES (DATEPART(yy, @Date), DATEPART(ISO_WEEK, @Date))
SET @Date = DATEADD(WK, 1, @Date)
SET @i = @i + 1
END
SELECT * FROM @yearsAndWeeks
DECLARE@yearsAndWeeks表(Year INT,Week INT)
声明@i INT
设置@i=0
声明@Date-DATETIME
设置@Date='20151231'
而@i<9
开始
在@yearsAndWeeks(Year,Week)值中插入日期部分(yy,Date),日期部分(ISO_Week,Date))
SET@Date=DATEADD(第1周,@Date)
设置@i=@i+1
结束
从@yearsAndWeeks中选择*
您可以根据需要连接。也不需要循环
SELECT
YEAR(DATEADD(week, X.Y, BaseDate)),
DATEPART(ISO_WEEK, DATEADD(week, X.Y, BaseDate))
FROM
(SELECT CAST('20151231' AS date) AS BaseDate) D
CROSS JOIN
(
VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8)
) AS X(Y);
更新SQL Server 2008添加了修复周编号的
根据SQL Server的说法,第2周将于2016年1月3日开始,这几乎可以奏效。这与ISO不同。您可以根据需要连接。也不需要循环
SELECT
YEAR(DATEADD(week, X.Y, BaseDate)),
DATEPART(ISO_WEEK, DATEADD(week, X.Y, BaseDate))
FROM
(SELECT CAST('20151231' AS date) AS BaseDate) D
CROSS JOIN
(
VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8)
) AS X(Y);
更新SQL Server 2008添加了修复周编号的
根据SQL Server的说法,第2周将于2016年1月3日开始,这几乎可以奏效。这与ISO不同。@Date是需要周数据的开始日期,@NumberOfWeeks是需要数据的后续周数。请根据需要修改这些值
--Create the temp table to hold the data
IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
DROP TABLE #Dates;
CREATE TABLE #Dates
( [Year] INT NOT NULL,
[WeekNumber] INT NOT NULL,
[RequiredWeek] NVARCHAR(255) NOT NULL,
[Date] DATETIME NOT NULL
);
--DECLARE @Date Datetime='2016-1-1'; --for testing
--DECLARE @Date Datetime='2016-12-31'; --for testing
DECLARE @Date Datetime='2015-12-31';
DECLARE @Days INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr INT=0;
SET @NumberOfWeeks=9
WHILE @Ctr<@NumberOfWeeks
BEGIN
SET @Days=@Ctr*7
INSERT INTO #Dates
SELECT DATEPART(YEAR,@Date+@Days) AS [Year],
DATEPART(wk,@Date+@Days) AS [WeekNumber],
CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
@Date+@Days AS [Date]
SET @Ctr=@Ctr+1
END
SELECT * FROM #Dates;
@Date是您需要周数据的开始日期,@NumberOfWeeks是您需要数据的后续周数。请根据需要修改这些值
--Create the temp table to hold the data
IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
DROP TABLE #Dates;
CREATE TABLE #Dates
( [Year] INT NOT NULL,
[WeekNumber] INT NOT NULL,
[RequiredWeek] NVARCHAR(255) NOT NULL,
[Date] DATETIME NOT NULL
);
--DECLARE @Date Datetime='2016-1-1'; --for testing
--DECLARE @Date Datetime='2016-12-31'; --for testing
DECLARE @Date Datetime='2015-12-31';
DECLARE @Days INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr INT=0;
SET @NumberOfWeeks=9
WHILE @Ctr<@NumberOfWeeks
BEGIN
SET @Days=@Ctr*7
INSERT INTO #Dates
SELECT DATEPART(YEAR,@Date+@Days) AS [Year],
DATEPART(wk,@Date+@Days) AS [WeekNumber],
CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
@Date+@Days AS [Date]
SET @Ctr=@Ctr+1
END
SELECT * FROM #Dates;
为了进一步根据您的需要进行定制,并冒着使此解决方案非通用的风险,以下代码给出了2015W53之后的2016W1,假设起始日期为“2015年12月31日”
--Create the temp table
IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
DROP TABLE #Dates;
CREATE TABLE #Dates
( [Year] INT NOT NULL,
[WeekNumber] INT NOT NULL,
[RequiredWeek] NVARCHAR(255) NOT NULL,
[Date] DATETIME NOT NULL
);
--DECLARE @Date Datetime='2016-1-1';
--DECLARE @Date Datetime='2016-12-31';
DECLARE @Date Datetime='2015-12-31';
DECLARE @Days INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr INT=0;
SET @NumberOfWeeks=9
WHILE @Ctr<@NumberOfWeeks
BEGIN
IF (@Date ='2015-12-31' AND @Ctr=1) -- To handle 1st week of Jan 2016
SET @Days=@Ctr+1
else if (@Date ='2015-12-31' AND @Ctr=0) --To Handle last week of Dec 2015
SET @Days=(@Ctr)*7
else
SET @Days=(@Ctr-1)*7 --for rest of the weeks of 2016
INSERT INTO #Dates
SELECT DATEPART(YEAR,@Date+@Days) AS [Year],
DATEPART(wk,@Date+@Days) AS [WeekNumber],
CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
@Date+@Days AS [Date]
SET @Ctr=@Ctr+1
END
SELECT * FROM #Dates;
--创建临时表
如果对象ID('TempDB..#Dates')不为空
删除表格#日期;
创建表#日期
([Year]INT不为空,
[WeekNumber]整数不为空,
[RequiredWeek]NVARCHAR(255)不为空,
[日期]日期时间不为空
);
--声明@Date Datetime='2016-1-1';
--声明@Date Datetime='2016-12-31';
声明@Date Datetime='2015-12-31';
声明@Days INT;
声明@NumberOfWeeks INT;
声明@Ctr INT=0;
设置@NumberOfWeeks=9
尽管@Ctr为了进一步根据您的需要进行定制,并且有可能使此解决方案成为非通用解决方案,但以下代码给出了2015W53之后的2016W1,假设起始日期为“2015年12月31日”
--Create the temp table
IF OBJECT_ID('TempDB..#Dates') IS NOT NULL
DROP TABLE #Dates;
CREATE TABLE #Dates
( [Year] INT NOT NULL,
[WeekNumber] INT NOT NULL,
[RequiredWeek] NVARCHAR(255) NOT NULL,
[Date] DATETIME NOT NULL
);
--DECLARE @Date Datetime='2016-1-1';
--DECLARE @Date Datetime='2016-12-31';
DECLARE @Date Datetime='2015-12-31';
DECLARE @Days INT;
DECLARE @NumberOfWeeks INT;
DECLARE @Ctr INT=0;
SET @NumberOfWeeks=9
WHILE @Ctr<@NumberOfWeeks
BEGIN
IF (@Date ='2015-12-31' AND @Ctr=1) -- To handle 1st week of Jan 2016
SET @Days=@Ctr+1
else if (@Date ='2015-12-31' AND @Ctr=0) --To Handle last week of Dec 2015
SET @Days=(@Ctr)*7
else
SET @Days=(@Ctr-1)*7 --for rest of the weeks of 2016
INSERT INTO #Dates
SELECT DATEPART(YEAR,@Date+@Days) AS [Year],
DATEPART(wk,@Date+@Days) AS [WeekNumber],
CAST(DATEPART(YEAR,@Date+@Days) AS VARCHAR(10))+'W'+ CAST(DATEPART(wk,@Date+@Days) AS VARCHAR(10)) AS [RequiredWeek],
@Date+@Days AS [Date]
SET @Ctr=@Ctr+1
END
SELECT * FROM #Dates;
--创建临时表
如果对象ID('TempDB..#Dates')不为空
删除表格#日期;
创建表#日期
([Year]INT不为空,
[WeekNumber]整数不为空,
[RequiredWeek]NVARCHAR(255)不为空,
[日期]日期时间不为空
);
--声明@Date Datetime='2016-1-1';
--声明@Date Datetime='2016-12-31';
声明@Date Datetime='2015-12-31';
声明@Days INT;
声明@NumberOfWeeks INT;
声明@Ctr INT=0;
设置@NumberOfWeeks=9
虽然@CtrIt看起来您的代码正试图生成前导零,即2016W01
而不是2016W1
如您的规范所示。(FWIW我认为前导零更好!)但看起来您的代码正试图生成前导零,即2016W01
而不是2016W1
如您的规范所示。(FWIW我认为前导零更好!)这里我得到的输出缺少第1周,2015W522016W02我缺少第1周…正如预期的那样,根据我的链接+1-与我的解决方案相同,但更优雅:-)我不知道你可以这样做@gbn选择DatePart(周,'20160101')作为周,选择DatePart(Iso_周,'20160101')作为Iso周。这里我的输出是第1周和第53周,我想要ISO8601格式,请提供任何帮助…@gbn我在该链接中没有看到任何关于跳过第1周的内容?或者这篇文章。在这里,我得到的输出缺少第1周,2015W522016W02我缺少第1周……正如预期的那样,根据我的链接+1-做的与我的解决方案相同,但更优雅:-)不知道你能做到@gbn选择DatePart(周,'20160101')作为周,选择DatePart(Iso_周,'20160101')作为Iso周。这里我的输出是第1周和第53周,我想要ISO8601格式,请提供任何帮助…@gbn我在该链接中没有看到任何关于跳过第1周的内容?或者这篇文章。但是在这里我可以得到2015W53,然后我想要2016w1。,这是不可能的吗?好吧,我加上7作为持续时间