T-SQL의 주 번호에서 날짜 가져오기
Microsoft SQL Server에는 주 번호가 있습니다.
(from DATEPART(wk, datecol))
하지만 제가 하고 싶은 것은 이것을 그 주의 날짜 범위로 되돌리는 것입니다.
예를들면,
SELECT DATEPART(wk, GETDATE())
yields 10
나는 도출하고 싶습니다.3/1/2009
그리고.3/7/2009
이 번호부터
이것이 가능합니까?
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에서 단순한 날짜 조작이 이렇게 난해해야 한다는 것은 미친 짓인 것 같습니다만...
@WeekNum 및 @YearNum을 원하는 대로 설정할 수 있습니다. 이 예에서는 설명을 위해 GETDATE()로 설정된 @datecol 변수에서 파생되었습니다.이러한 값이 설정되면 다음을 사용하여 한 주의 날짜 범위를 계산할 수 있습니다.
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;
질문에 대한 답변:
--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)))
한 주가 월요일부터 시작하는 경우(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
SELECT DATECOL - DATEPART(weekday, DATECOL), DATECOL - DATEPART(weekday, DATECOL) + 7
해당 주 번호의 이전 주로 점프한 다음 주 번호가 변경될 때까지 며칠 동안 단계를 밟아(최대 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
저는 엘린드블롬의 솔루션을 가져와서 수정했습니다. (날짜까지 캐스팅되더라도) 스트링을 사용하는 것은 전 세계에서 사용되는 다양한 형식의 날짜에 대해 긴장하게 만듭니다.이렇게 하면 해당 문제가 발생하지 않습니다.
요청하지는 않았지만 시간도 포함하여 자정 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
@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')
다른 방법:
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
설명:
- @week_number는 최초 달력 날짜 '2021-01-01'을 기준으로 계산됩니다.원하는 날짜로 getdate()를 바꿉니다.
- @start_weekday는 월요일인 경우 0입니다.일요일인 경우 -1로 선언합니다.
- @end_weekday는 다음 주 일요일이면 6시입니다.토요일인 경우 5로 선언합니다.
- 그리고나서
dateadd
함수는 지정된 주 수와 지정된 일 수를 최초 달력 날짜 '2021-01-01'에 추가합니다.
dateadd(
dd,
datepart(wk, @Date)*7,
convert(smalldatetime, convert(char,year(max(@Date)))+convert(char, '-01-01'))
)-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
은 이은다음상작합니다야동해이관없과것▁ofless▁regard▁work합▁this니다▁should와 상관없이 작동해야 합니다.@@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
나는 단지 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
올해 첫 주와 마지막 주를 제외하고는 가장 많은 표가 응답하는 것이 좋습니다.datecol 값이 '2009-01-01'이면 결과는 2009년 1월 3일과 2008년 12월 28일이 됩니다.
내 솔루션:
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;
첫 번째 주에는 01/01/2009 및 01/03/2009가 표시되고, 10번째 주에는 03/01/2009 및 03/07/2009가 표시됩니다.
이것이 정확히 당신이 원하는 것이라고 생각합니다.원하는 대로 변수를 식으로 바꿀 수 있습니다.
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
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'))
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
답변:
select DateAdd(day,-DATEPart(DW,<Date>), <Date>) [FirstDayOfWeek] ,DateAdd(day,-DATEPart(DW,<Date>)+6, <Date>) [LastDayOfWeek]
FROM <TABLE>
이것은 나에게 도움이 됩니다.
select
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 1, DATECOL), 101),
convert(varchar(50), dateadd(dd, - datepart(dw, DATECOL) + 7, DATECOL), 101)
여기에 있는 모든 답을 테스트하는 데 시간을 들이지는 않았지만, 이처럼 간단하고 효율적인 것은 없습니다.
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
언급URL : https://stackoverflow.com/questions/607817/get-dates-from-a-week-number-in-t-sql
'programing' 카테고리의 다른 글
마지막 Git add는 어떻게 취소할 수 있습니까? (0) | 2023.06.30 |
---|---|
vuex를 사용하여 단방향 바인딩을 구성합니다. (0) | 2023.06.30 |
Bash 스크립트: #!/bin/bash는 무엇을 의미합니까? (0) | 2023.06.30 |
junit5와 함께 SpringRunner를 사용하기 위한 특별한 구성이 있습니까? (0) | 2023.06.30 |
판다 데이터 프레임에서 유닉스 시간을 읽기 가능한 날짜로 변환 (0) | 2023.06.30 |