programing

주 번호에서 주 시작 날짜와 주 종료 날짜를 가져옵니다.

abcjava 2023. 4. 21. 20:06
반응형

주 번호에서 주 시작 날짜와 주 종료 날짜를 가져옵니다.

데이터베이스에서 멤버의 결혼 날짜를 세는 질문이 있습니다.

SELECT 
  SUM(NumberOfBrides) AS [Wedding Count]
  , DATEPART( wk, WeddingDate) AS [Week Number]
  , DATEPART( year, WeddingDate) AS [Year]
FROM  MemberWeddingDates
GROUP BY DATEPART(year, WeddingDate), DATEPART(wk, WeddingDate)
ORDER BY SUM(NumberOfBrides) DESC

각 주의 시작과 끝이 결과 세트에 나타나 있는 경우 어떻게 해야 합니까?

SELECT
  SUM(NumberOfBrides) AS [Wedding Count]
  , DATEPART(wk, WeddingDate) AS [Week Number]
  , DATEPART(year, WeddingDate) AS [Year]
  , ??? AS WeekStart
  , ??? AS WeekEnd
FROM  MemberWeddingDates
GROUP BY DATEPART(year, WeddingDate), DATEPART(wk, WeddingDate)
ORDER BY SUM(NumberOfBrides) DESC

요일을 찾아 날짜 추가를 수행하여 시작 날짜와 종료 날짜를 가져올 수 있습니다.

DATEADD(dd, -(DATEPART(dw, WeddingDate)-1), WeddingDate) [WeekStart]

DATEADD(dd, 7-(DATEPART(dw, WeddingDate)), WeddingDate) [WeekEnd]

당신은 아마 날짜에서 시간을 빼는 것도 보고 싶을 거예요.

여기 a가 있습니다.DATEFIRST독립 솔루션:

SET DATEFIRST 4     /* or use any other weird value to test it */
DECLARE @d DATETIME

SET @d = GETDATE()

SELECT
  @d ThatDate,
  DATEADD(dd, 0 - (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Monday,
  DATEADD(dd, 6 - (@@DATEFIRST + 5 + DATEPART(dw, @d)) % 7, @d) Sunday

다음의 것도 사용할 수 있습니다.

  SELECT DATEADD(day, DATEDIFF(day, 0, WeddingDate) /7*7, 0) AS weekstart,
         DATEADD(day, DATEDIFF(day, 6, WeddingDate-1) /7*7 + 7, 6) AS WeekEnd

여기 다른 버전이 있습니다.시나리오에서 토요일을 주의 첫 번째 요일로, 금요일을 주의 마지막 요일로 해야 하는 경우 다음 코드가 이를 처리합니다.

  DECLARE @myDate DATE = GETDATE()
  SELECT    @myDate,
    DATENAME(WEEKDAY,@myDate),
    DATEADD(DD,-(CHOOSE(DATEPART(dw, @myDate), 1,2,3,4,5,6,0)),@myDate) AS WeekStartDate,
    DATEADD(DD,7-CHOOSE(DATEPART(dw, @myDate), 2,3,4,5,6,7,1),@myDate) AS WeekEndDate

쿼리 스크린샷

@Tomalak의 답변을 확장합니다.이 수식은 일요일과 월요일 이외의 날에 사용할 수 있지만 5의 위치에 대해서는 다른 값을 사용해야 합니다.필요한 가치를 실현하는 방법은 다음과 같습니다.

Value Needed = 7 - (Value From Date First Documentation for Desired Day Of Week) - 1

다음 링크에서 문서를 참조해 주세요.https://msdn.microsoft.com/en-us/library/ms181598.aspx

그리고 여기 테이블이 있습니다.

          | DATEFIRST VALUE |   Formula Value   |   7 - DATEFIRSTVALUE - 1
Monday    | 1               |          5        |   7 - 1- 1 = 5
Tuesday   | 2               |          4        |   7 - 2 - 1 = 4
Wednesday | 3               |          3        |   7 - 3 - 1 = 3
Thursday  | 4               |          2        |   7 - 4 - 1 = 2
Friday    | 5               |          1        |   7 - 5 - 1 = 1
Saturday  | 6               |          0        |   7 - 6 - 1 = 0
Sunday    | 7               |         -1        |   7 - 7 - 1 = -1

그러나 이 표를 기억할 필요는 없고 공식만 기억할 필요는 없으며, 실제로 약간 다른 표를 사용할 수도 있습니다. 가장 중요한 필요성은 나머지를 올바른 일수로 만드는 값을 사용하는 것입니다.

다음으로 작업 예를 제시하겠습니다.

DECLARE @MondayDateFirstValue INT = 1
DECLARE @FridayDateFirstValue INT = 5
DECLARE @TestDate DATE = GETDATE()

SET @MondayDateFirstValue = 7 - @MondayDateFirstValue - 1
SET @FridayDateFirstValue = 7 - @FridayDateFirstValue - 1

SET DATEFIRST 6 -- notice this is saturday

SELECT 
    DATEADD(DAY, 0 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as MondayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as MondayEndOfWeek
   ,DATEADD(DAY, 0 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as FridayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as FridayEndOfWeek


SET DATEFIRST 2 --notice this is tuesday

SELECT 
    DATEADD(DAY, 0 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as MondayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @MondayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as MondayEndOfWeek
   ,DATEADD(DAY, 0 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate)  as FridayStartOfWeek
    ,DATEADD(DAY, 6 - (@@DATEFIRST + @FridayDateFirstValue + DATEPART(dw,@TestDate)) % 7, @TestDate) as FridayEndOfWeek

이 방법은 다음과 같습니다.DATEFIRST여러 주간 방식을 포함한 날짜 치수를 작성하기 위해 필요한 설정입니다.

일요일이 주 시작 요일로 간주되는 경우, 다음은 코드입니다.

Declare @currentdate date = '18 Jun 2020'

select DATEADD(D, -(DATEPART(WEEKDAY, @currentdate) - 1), @currentdate)

select DATEADD(D, (7 - DATEPART(WEEKDAY, @currentdate)), @currentdate)

아래 쿼리는 일요일부터 토요일까지 현재 주의 시작과 끝 사이의 데이터를 제공합니다.

SELECT DOB FROM PROFILE_INFO WHERE DAY(DOB) BETWEEN
DAY( CURRENT_DATE() - (SELECT DAYOFWEEK(CURRENT_DATE())-1))
AND
DAY((CURRENT_DATE()+(7 - (SELECT DAYOFWEEK(CURRENT_DATE())) ) ))
AND
MONTH(DOB)=MONTH(CURRENT_DATE())

문제를 두 부분으로 나누어 보겠습니다.

1) 요일 결정

DATEPART(dw, ...)에 상대적인 숫자 1...7을 반환합니다.DATEFIRST설정(예:다음 표에 사용 가능한 값을 정리합니다.

                                                   @@DATEFIRST
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
|                                    |  1  |  2  |  3  |  4  |  5  |  6  |  7  | DOW |
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+
|  DATEPART(dw, /*Mon*/ '20010101')  |  1  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |
|  DATEPART(dw, /*Tue*/ '20010102')  |  2  |  1  |  7  |  6  |  5  |  4  |  3  |  2  |
|  DATEPART(dw, /*Wed*/ '20010103')  |  3  |  2  |  1  |  7  |  6  |  5  |  4  |  3  |
|  DATEPART(dw, /*Thu*/ '20010104')  |  4  |  3  |  2  |  1  |  7  |  6  |  5  |  4  |
|  DATEPART(dw, /*Fri*/ '20010105')  |  5  |  4  |  3  |  2  |  1  |  7  |  6  |  5  |
|  DATEPART(dw, /*Sat*/ '20010106')  |  6  |  5  |  4  |  3  |  2  |  1  |  7  |  6  |
|  DATEPART(dw, /*Sun*/ '20010107')  |  7  |  6  |  5  |  4  |  3  |  2  |  1  |  7  |
+------------------------------------+-----+-----+-----+-----+-----+-----+-----+-----+

마지막 열에는 월요일부터 일요일까지 이상적인 요일 값이 포함됩니다*.차트를 보는 것만으로 다음과 같은 방정식을 얻을 수 있습니다.

(@@DATEFIRST + DATEPART(dw, SomeDate) - 1 - 1) % 7 + 1

2) 지정된 날짜의 월요일과 일요일 계산

day-of-week 값 때문에 이것은 사소한 것입니다.다음은 예를 제시하겠습니다.

WITH TestData(SomeDate) AS (
    SELECT CAST('20001225' AS DATETIME) UNION ALL
    SELECT CAST('20001226' AS DATETIME) UNION ALL
    SELECT CAST('20001227' AS DATETIME) UNION ALL
    SELECT CAST('20001228' AS DATETIME) UNION ALL
    SELECT CAST('20001229' AS DATETIME) UNION ALL
    SELECT CAST('20001230' AS DATETIME) UNION ALL
    SELECT CAST('20001231' AS DATETIME) UNION ALL
    SELECT CAST('20010101' AS DATETIME) UNION ALL
    SELECT CAST('20010102' AS DATETIME) UNION ALL
    SELECT CAST('20010103' AS DATETIME) UNION ALL
    SELECT CAST('20010104' AS DATETIME) UNION ALL
    SELECT CAST('20010105' AS DATETIME) UNION ALL
    SELECT CAST('20010106' AS DATETIME) UNION ALL
    SELECT CAST('20010107' AS DATETIME) UNION ALL
    SELECT CAST('20010108' AS DATETIME) UNION ALL
    SELECT CAST('20010109' AS DATETIME) UNION ALL
    SELECT CAST('20010110' AS DATETIME) UNION ALL
    SELECT CAST('20010111' AS DATETIME) UNION ALL
    SELECT CAST('20010112' AS DATETIME) UNION ALL
    SELECT CAST('20010113' AS DATETIME) UNION ALL
    SELECT CAST('20010114' AS DATETIME)
), TestDataPlusDOW AS (
    SELECT SomeDate, (@@DATEFIRST + DATEPART(dw, SomeDate) - 1 - 1) % 7 + 1 AS DOW
    FROM TestData
)
SELECT
    FORMAT(SomeDate,                            'ddd yyyy-MM-dd') AS SomeDate,
    FORMAT(DATEADD(dd, -DOW + 1, SomeDate),     'ddd yyyy-MM-dd') AS [Monday],
    FORMAT(DATEADD(dd, -DOW + 1 + 6, SomeDate), 'ddd yyyy-MM-dd') AS [Sunday]
FROM TestDataPlusDOW

출력:

+------------------+------------------+------------------+
|  SomeDate        |  Monday          |    Sunday        |
+------------------+------------------+------------------+
|  Mon 2000-12-25  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Tue 2000-12-26  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Wed 2000-12-27  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Thu 2000-12-28  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Fri 2000-12-29  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Sat 2000-12-30  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Sun 2000-12-31  |  Mon 2000-12-25  |  Sun 2000-12-31  |
|  Mon 2001-01-01  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Tue 2001-01-02  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Wed 2001-01-03  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Thu 2001-01-04  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Fri 2001-01-05  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Sat 2001-01-06  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Sun 2001-01-07  |  Mon 2001-01-01  |  Sun 2001-01-07  |
|  Mon 2001-01-08  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Tue 2001-01-09  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Wed 2001-01-10  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Thu 2001-01-11  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Fri 2001-01-12  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Sat 2001-01-13  |  Mon 2001-01-08  |  Sun 2001-01-14  |
|  Sun 2001-01-14  |  Mon 2001-01-08  |  Sun 2001-01-14  |
+------------------+------------------+------------------+

* 일요일부터 토요일까지는 방정식을 약간만 조정하면 됩니다. 예를 들어 1을 더하는 등입니다.

이번 사건에서도 비슷한 사례를 접했을 뿐이지만, 이 해결 방법은 도움이 되지 않는 것 같습니다.그래서 스스로 알아내려고 노력해요.저는 주 시작 날짜만 계산하고, 주 종료 날짜는 비슷한 논리로 해야 합니다.

Select 
      Sum(NumberOfBrides) As [Wedding Count], 
      DATEPART( wk, WeddingDate) as [Week Number],
      DATEPART( year, WeddingDate) as [Year],
      DATEADD(DAY, 1 - DATEPART(WEEKDAY, dateadd(wk, DATEPART( wk, WeddingDate)-1,  DATEADD(yy,DATEPART( year, WeddingDate)-1900,0))), dateadd(wk, DATEPART( wk, WeddingDate)-1, DATEADD(yy,DATEPART( year, WeddingDate)-1900,0))) as [Week Start]

FROM  MemberWeddingDates
Group By DATEPART( year, WeddingDate), DATEPART( wk, WeddingDate)
Order By Sum(NumberOfBrides) Desc

1년 중 첫째 주와 마지막 주를 제외하고 가장 많이 투표된 답변이 정상적으로 작동합니다.예를 들어 WeddingDate 값이 '2016-01-01'이면 2015-12-272016-01-02가 되지만 정답은 2016-01-012016-01-02다.

이것을 시험해 보세요.

Select 
  Sum(NumberOfBrides) As [Wedding Count], 
  DATEPART( wk, WeddingDate) as [Week Number],
  DATEPART( year, WeddingDate) as [Year],
  MAX(CASE WHEN DATEPART(WEEK, WeddingDate) = 1 THEN CAST(DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0) AS date) ELSE DATEADD(DAY, 7 * DATEPART(WEEK, WeddingDate), DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0))) END) as WeekStart,
  MAX(CASE WHEN DATEPART(WEEK, WeddingDate) = DATEPART(WEEK, DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate) + 1, 0))) THEN DATEADD(DAY, -1, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate) + 1, 0)) ELSE DATEADD(DAY, 7 * DATEPART(WEEK, WeddingDate) + 6, DATEADD(DAY, -(DATEPART(WEEKDAY, DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0)) + 6), DATEADD(YEAR, DATEDIFF(YEAR, 0, WeddingDate), 0))) END) as WeekEnd
FROM  MemberWeddingDates
Group By DATEPART( year, WeddingDate), DATEPART( wk, WeddingDate)
Order By Sum(NumberOfBrides) Desc;

과 같습니다.여기에 이미지 설명 입력

첫 번째 주부터 다른 주까지 계속 작동합니다.

Power BI Dax 공식의 시작일과 종료일로부터 주의 시작일

WeekStartDate = [DateColumn] - (WEEKDAY([DateColumn])-1)
WeekEndDate = [DateColumn] + (7-WEEKDAY([DateColumn]))

이것이 나의 해결책이다.


SET DATEFIRST 1; /* 다른 datefirst를 사용하도록 변경 */@date DATETIME 선언SET @date = CAST(날짜로는 '2019년 2월 6일')
DATEADD(dd,0 - (DATEPART(dw,@date)-1), @date) [dateFrom],DATEADD(dd, 6 - (DATEPART(dw, @date) - 1) ,@date) [날짜 종료]

커스텀 날짜별로 시작 날짜와 종료 날짜를 가져옵니다.


   DECLARE @Date NVARCHAR(50)='05/19/2019' 
   SELECT
      DATEADD(DAY,CASE WHEN DATEPART(WEEKDAY, @Date)=1 THEN -6 ELSE 2 - DATEPART(WEEKDAY, @Date) END, CAST(@Date AS DATE)) [Week_Start_Date]
     ,DATEADD(DAY,CASE WHEN DATEPART(WEEKDAY, @Date)=1 THEN 0 ELSE  8 - DATEPART(WEEKDAY, @Date) END, CAST(@Date AS DATE)) [Week_End_Date]

또 다른 방법:

declare @week_number int = 6280 -- 2020-05-07
declare @start_weekday int = 0 -- Monday
declare @end_weekday int = 6 -- next Sunday

select 
    dateadd(week, @week_number, @start_weekday), 
    dateadd(week, @week_number, @end_weekday)

설명:

  • @week_number는 최초 캘린더 날짜 '1901-01' 이후의 주 번호입니다.다음과 같이 계산할 수 있습니다.select datediff(week, 0, @wedding_date) as week_number
  • @start_weekday는 주의 첫날: 월요일은 0, 일요일은 -1
  • @end_weekday(지난 주): 다음 주 일요일은 6개, 토요일은 5개
  • dateadd(week, @week_number, @end_weekday): 첫 번째 달력 날짜 '1901-01'에 지정된 주수와 지정된 일수를 추가합니다.

이건 내가 한 말이 아니야. 하지만 그건 상관 없이 해냈지.

SELECT DATEADD(wk, -1, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day previous week
SELECT DATEADD(wk, 0, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day current week
SELECT DATEADD(wk, 1, DATEADD(DAY, 1-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --first day next week

SELECT DATEADD(wk, 0, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day previous week
SELECT DATEADD(wk, 1, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day current week
SELECT DATEADD(wk, 2, DATEADD(DAY, 0-DATEPART(WEEKDAY, GETDATE()), DATEDIFF(dd, 0, GETDATE()))) --last day next week

여기서 찾았어.

다른 방법이 있습니다. 현재 day Start와 day End of Week Current를 선택합니다.

DATEADD(d, -(DATEPART(dw, GETDATE()-2)), GETDATE()) is date time Start

그리고.

DATEADD(day,7-(DATEPART(dw,GETDATE()-1)),GETDATE()) is date time End

다음 SQL 코드를 사용하여 모든 시작 요일 또는 종료 요일 또는 n번째 요일을 가져올 수 있습니다.

SELECT DateList.MyDay, DateAdd("d",1-Weekday([MyDay],2),[MyDay]) AS DateAdd FROM DateList;

이것이 얼마나 유용한지는 모르겠지만, Netezza SQL에서 솔루션을 찾다가 스택 오버플로에서 솔루션을 찾을 수 없었습니다.

IBM netezza의 경우 다음과 같은 것(주차 시작 월, 주 종료 일광)을 사용합니다.

select
next_day (WeddingDate, 'SUN') -6 as WeekStart,

next_day (WeddingDate, 'SUN') as WeekEnd

[ Access Queries ]의 경우 다음 형식으로 필드를 사용할 수 있습니다.

"FirstDayofWeek:IIf(IsDate([ForwardedForActionDate]),CDate(Format([ForwardedForActionDate],"dd/mm/yyyy"))-(Weekday([ForwardedForActionDate])-1))"

직접 계산이 허용됩니다.

언급URL : https://stackoverflow.com/questions/1267126/get-the-week-start-date-and-week-end-date-from-week-number

반응형