在Microsoft SQL Server中,我有一个周编号
(from DATEPART(wk, datecol))
但我想做的是将其重新转换为该周的日期范围。
例如,
SELECT DATEPART(wk, GETDATE())
产生10.我想从这个数字得出3/1/2009和3/7/2009。
这可能吗?
答案 0 :(得分:31)
Quassnoi的回答是有效的,但是如果他们是在一天中间的日期,那么你可以把日期清理干净(他的开始时间比你使用时间要早一天。在一天的中间 - 您可以使用GETDATE()进行测试。
我过去曾经使用过这样的东西:
SELECT
CONVERT(varchar(50), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, DATECOL), DATECOL)), 101),
CONVERT(varchar(50), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, DATECOL) - 6, DATECOL)), 101)
这样做的另一个好处是,通过使用@@ DATEFIRST,您可以处理非标准的周开始日期(默认为星期日,但使用SET @@ DATEFIRST,您可以更改此日期)。
似乎很疯狂,SQL Server中的简单日期操作必须是这个神秘的,但是你去了......
答案 1 :(得分:16)
您可以将@WeekNum和@YearNum设置为您想要的任何内容 - 在此示例中,它们是从@datecol变量派生的,为了说明的目的,该变量设置为GETDATE()。获得这些值后,您可以使用以下方法计算一周的日期范围:
DECLARE @datecol datetime = GETDATE(); DECLARE @WeekNum INT , @YearNum char(4); SELECT @WeekNum = DATEPART(WK, @datecol) , @YearNum = CAST(DATEPART(YY, @datecol) AS CHAR(4)); -- once you have the @WeekNum and @YearNum set, the following calculates the date range. SELECT DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + @YearNum) + (@WeekNum-1), 6) AS StartOfWeek; SELECT DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + @YearNum) + (@WeekNum-1), 5) AS EndOfWeek;
答案 2 :(得分:4)
如果您的周从星期一开始(在SQL Server 2008上)
select datecol,
DATEPART(ISOWK, datecol) as week,
((DATEPART(dw, datecol)+5)%7)+1 as weekday,
(DATEADD(dd, -((DATEPART(dw, datecol)+5)%7), datecol)) as Monday,
(DATEADD(dd, -((DATEPART(dw, datecol)+5)%7)+6, datecol)) as Sunday
答案 3 :(得分:4)
回答你的问题:
--CHANGE A WEEK NUMBER BACK INTO A DATE FOR THE FIRST DATE OF THE WEEK
DECLARE @TaskWeek INT = 17
DECLARE @TaskYear INT = 2013
SELECT DATEADD(WEEK, @TaskWeek - 1,DATEADD(dd, 1 - DATEPART(dw, '1/1/' + CONVERT(VARCHAR(4),@TaskYear)), '1/1/' + CONVERT(VARCHAR(4),@TaskYear)))
答案 4 :(得分:3)
如果一个函数跳转到该周数之前的那一周,然后逐步完成接下来的几天直到周数改变(最多7个步骤),返回新的日期?
CREATE FUNCTION dbo.fnGetDateFromWeekNo
(@weekNo int , @yearNo int)
RETURNS smalldatetime
AS
BEGIN
DECLARE @tmpDate smalldatetime
set @tmpdate= cast(cast (@yearNo as varchar) + '-01-01' as smalldatetime)
-- jump forward x-1 weeks to save counting through the whole year
set @tmpdate=dateadd(wk,@weekno-1,@tmpdate)
-- make sure weekno is not out of range
if @WeekNo <= datepart(wk,cast(cast (@yearNo as varchar) + '-12-31' as smalldatetime))
BEGIN
WHILE (datepart(wk,@tmpdate)<@WeekNo)
BEGIN
set @tmpdate=dateadd(dd,1,@tmpdate)
END
END
ELSE
BEGIN
-- invalid weeknumber given
set @tmpdate=null
END
RETURN @tmpDate
END
答案 5 :(得分:3)
SELECT DATECOL - DATEPART(weekday, DATECOL), DATECOL - DATEPART(weekday, DATECOL) + 7
答案 6 :(得分:1)
无论@@DATEFIRST
ALTER FUNCTION dbo.DEV_VW_WeekSerial
(@YearNum int,
@WeekNum int,
@DayNum int)
RETURNS Date AS
BEGIN
DECLARE @FirstDayYear As Date;
SET @FirstDayYear='01/01/' + CAST(@YearNum As varchar)
RETURN dateadd(d,(@DayNum-datepart(weekday,@FirstDayYear)),dateadd(week, @WeekNum-1,@FirstDayYear))
END
答案 7 :(得分:1)
dateadd(
dd,
datepart(wk, @Date)*7,
convert(smalldatetime, convert(char,year(max(@Date)))+convert(char, '-01-01'))
)-1
答案 8 :(得分:1)
在这里你只需要传递年份和周数。
DECLARE @Year VARCHAR(4)
SET @Year= '2012'
DECLARE @FirstDate DATETIME
SET @FirstDate = (SELECT DATEADD(dd,1,(SELECT DATEADD(wk,DATEPART(wk,GETDATE())-1,Convert(DAteTime,'01-01-' + @Year))))
)
DECLARE @LastDate DATETIME
SET @LastDate =(SELECT DATEADD(dd,4,@FirstDate))
SELECT @FirstDate
,@LastDate
答案 9 :(得分:1)
我采用了elindeblom的解决方案并对其进行了修改 - 字符串的使用(即使投射到日期)让我对世界各地使用的不同日期格式感到紧张。这避免了这个问题。
虽然没有要求,但我还包括时间,所以一周在午夜前1秒结束:
DECLARE @WeekNum INT = 12,
@YearNum INT = 2014 ;
SELECT DATEADD(wk,
DATEDIFF(wk, 6,
CAST(RTRIM(@YearNum * 10000 + 1 * 100 + 1) AS DATETIME))
+ ( @WeekNum - 1 ), 6) AS [start_of_week],
DATEADD(second, -1,
DATEADD(day,
DATEDIFF(day, 0,
DATEADD(wk,
DATEDIFF(wk, 5,
CAST(RTRIM(@YearNum * 10000
+ 1 * 100 + 1) AS DATETIME))
+ ( @WeekNum + -1 ), 5)) + 1, 0)) AS [end_of_week] ;
是的,我知道我还在投掷但是来自一个号码。它对我来说“感觉”更安全。
这导致:
start_of_week end_of_week
----------------------- -----------------------
2014-03-16 00:00:00.000 2014-03-22 23:59:59.000
答案 10 :(得分:1)
给它@Year和@Week, 返回该周的第一个日期。
Declare @Year int
,@Week int
,@YearText varchar(4)
set @Year = 2009
set @Week = 10
set @YearText = @Year
print dateadd(day
,1 - datepart(dw, @YearText + '-01-01')
+ (@Week-1) * 7
,@YearText + '-01-01')
答案 11 :(得分:1)
我刚刚将SELECT与CASE语句合并(对于我的情况,星期一标记了一周的第一天,并且不想处理SET DATEFIRST命令:
CASE DATEPART(dw,<YourDateTimeField>)
WHEN 1 THEN CONVERT(char(10), DATEADD(DD, -6, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), <YourDateTimeField>,126)
WHEN 2 THEN CONVERT(char(10), <YourDateTimeField>,126) + ' to ' + CONVERT(char(10), DATEADD(DD, 6, <YourDateTimeField>),126)
WHEN 3 THEN CONVERT(char(10), DATEADD(DD, -1, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 5, <YourDateTimeField>),126)
WHEN 4 THEN CONVERT(char(10), DATEADD(DD, -2, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 4, <YourDateTimeField>),126)
WHEN 5 THEN CONVERT(char(10), DATEADD(DD, -3, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 3, <YourDateTimeField>),126)
WHEN 6 THEN CONVERT(char(10), DATEADD(DD, -4, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 2, <YourDateTimeField>),126)
WHEN 7 THEN CONVERT(char(10), DATEADD(DD, -5, <YourDateTimeField>),126) + ' to ' + CONVERT(char(10), DATEADD(DD, 1, <YourDateTimeField>),126)
ELSE 'UNK'
END AS Week_Range
答案 12 :(得分:1)
除了第一周和上周之外,最多的投票答案工作正常。当 datecol 值'2009-01-01'时,结果将为 01/03/2009 和 12/28 / 2008 强>
我的解决方案:
DECLARE @Date date = '2009-03-01', @WeekNum int, @StartDate date;
SELECT @WeekNum = DATEPART(WEEK, @Date);
SELECT @StartDate = DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0));
SELECT CONVERT(nvarchar, CASE WHEN @WeekNum = 1 THEN CAST(DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0) AS date) ELSE DATEADD(DAY, 7 * @WeekNum, @StartDate) END, 101) AS StartOfWeek
,CONVERT(nvarchar, CASE WHEN @WeekNum = DATEPART(WEEK, DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date) + 1, 0))) THEN DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date) + 1, 0)) ELSE DATEADD(DAY, 7 * @WeekNum + 6, @StartDate) END, 101) AS EndOfWeek;
第1周将显示 01/01/2009 和 01/03/2009 ,并显示 03/01/2009 并且 03/07/2009 为第10周。
我认为这就是你想要的。您可以根据需要将变量替换为其表达式。
答案 13 :(得分:1)
declare @IntWeek as varchar(20)
SET @IntWeek = '201820'
SELECT
DATEADD(wk, DATEDIFF(wk, @@DATEFIRST, LEFT(@IntWeek,4) + '-01-01') +
(cast(RIGHT(@IntWeek, 2) as int) -1), @@DATEFIRST) AS StartOfWeek
答案 14 :(得分:0)
DECLARE @dayval int,
@monthval int,
@yearval int
SET @dayval = 1
SET @monthval = 1
SET @yearval = 2011
DECLARE @dtDateSerial datetime
SET @dtDateSerial = DATEADD(day, @dayval-1,
DATEADD(month, @monthval-1,
DATEADD(year, @yearval-1900, 0)
)
)
DECLARE @weekno int
SET @weekno = 53
DECLARE @weekstart datetime
SET @weekstart = dateadd(day, 7 * (@weekno -1) - datepart (dw, @dtDateSerial), @dtDateSerial)
DECLARE @weekend datetime
SET @weekend = dateadd(day, 6, @weekstart)
SELECT @weekstart, @weekend
答案 15 :(得分:0)
SELECT DATEADD(week, @weekNumber - 1, DATEADD(DAY, @@datefirst - DATEPART(weekday, CAST(YEAR(GETDATE()) AS VARCHAR) + '-01-01') - 6, CAST(YEAR(GETDATE()) AS VARCHAR) + '-01-01'))
答案 16 :(得分:0)
<强>答案:强>
select DateAdd(day,-DATEPart(DW,<Date>), <Date>) [FirstDayOfWeek] ,DateAdd(day,-DATEPart(DW,<Date>)+6, <Date>) [LastDayOfWeek]
FROM <TABLE>
答案 17 :(得分:0)
这对我有用:
select
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 1, DATECOL), 101),
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 7, DATECOL), 101)
答案 18 :(得分:0)
我没有花时间在这里测试每个答案,但似乎没有什么比这更简单和有效:
DECLARE @WeekNum int
DECLARE @YearNum char(4)
SELECT DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + @YearNum) + (@WeekNum-1), 6) AS StartOfWeek
SELECT DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + @YearNum) + (@WeekNum-1), 5) AS EndOfWeek
答案 19 :(得分:0)
另一种方法:
declare @week_number int;
declare @start_weekday int = 0 -- Monday
declare @end_weekday int = 6 -- next Sunday
select @week_number = datediff(week, 0, getdate())
select
dateadd(week, @week_number, @start_weekday) as WEEK_FIRST_DAY,
dateadd(week, @week_number, @end_weekday) as WEEK_LAST_DAY
说明:
dateadd
函数会将给定的星期数和天数添加到初始日历日期“ 1900-01-01”。