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


98

데이터베이스에 회원의 결혼 날짜를 계산하는 쿼리가 있습니다.

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

답변:


161

요일을 찾고 시작일과 종료일을 얻기 위해 날짜를 추가 할 수 있습니다.

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

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

당신은 또한 날짜에서 시간을 제거하는 것을보고 싶을 것입니다.


3
DATEFIRST7 이외의 값으로 설정 하면이를 깨뜨릴 수 있습니다.
Tomalak

5
"break"하지 않고 datefirst를 사용하여 WeekStart =를 DateFirst가 한주의 첫날이라고 말하는 것으로 설정합니다. 버전은 항상 월요일과 일요일을 한주의 시작과 끝으로 수행하며 서버가주의 시작과 끝으로 사용하도록 설정된 것이 아닙니다
Robin Day

1
흠 ... 그건 유효한 포인트입니다, +1. :) 나는 내 것을 지울 것입니다 (발에 총을 맞았지만 매우 잘 조준되었습니다. g ).
Tomalak

1
그럼 다시 삭제를 취소합니다. 나는 그들의 올바른 마음으로 월요일이 아닌 다른 것을 어쨌든 일주일의 시작으로 생각할 것인지 확신하지 못합니다. 주를 일요일에 시작하는 것은 전혀 의미가 없습니다 . :-)
Tomalak

3
월요일에 대한 'set datefirst 1'( msdn.microsoft.com/en-ie/library/ms181598.aspx )
Selrac

41

다음은 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

11
이것은 훌륭하지만 월요일은 나를 위해 일하지 않았습니다. 월요일을 가져 오려면 "0-"을 추가해야했습니다. 내 월요일 코드는 다음과 같습니다. DATEADD (dd, 0-(@@ DATEFIRST + 5 + DATEPART (dw, @d)) % 7, @d)
Warren

답변과 Warrens의 의견을 모두 찬성했습니다. Sql Server 버전 11.0.5058.0은 Warrens 수정없이 월요일에 대해 잘못된 날짜를 제공합니다. 대신 나에게 금요일을주고 있었다.
Morvael

18

이것을 사용할 수도 있습니다.

  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

2

@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여러 주 방법이 포함 된 날짜 차원을 구축 할 때 필요한 설정과 무관합니다.


2

다음은 다른 버전입니다. 시나리오에서 토요일이주의 1 일이고 금요일이 마지막 날인 경우 아래 코드가이를 처리합니다.

  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

쿼리 스크린 샷


1

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

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

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

1) 요일 결정

는 설정 ( docs ) 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) 주어진 날짜의 월요일과 일요일을 계산하십시오.

이는 요일 값 덕분에 사소한 일입니다. 다음은 예입니다.

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을 더하는 것과 같이 방정식을 약간 조정해야합니다.


1

일요일이 주 시작일로 간주되는 경우 코드는 다음과 같습니다.

Declare @currentdate date = '18 Jun 2020'

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

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

0

나는 이것과 비슷한 경우를 만났지만 여기의 해결책은 나를 돕지 않는 것 같습니다. 그래서 스스로 알아 내려고합니다. 주 시작일 만 계산하고, 주 종료일은 비슷한 논리 여야합니다.

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

0

가장 많이 투표 한 답변은 다음을 제외하고 잘 작동합니다. 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;

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

모든 주, 1 일 또는 기타 기간 동안 작동합니다.


0

Power BI Dax Formula의 시작 날짜 및 시작 날짜

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

0

이것은 내 해결책입니다

    SET DATEFIRST 1; / * 다른 날짜를 사용하도록 변경 먼저 * /
    @date DATETIME 선언
    SET @date = CAST ( '2/6/2019'를 날짜로)

    SELECT DATEADD (dd, 0-(DATEPART (dw, @date)-1), @ date) [dateFrom], 
            DATEADD (dd, 6-(DATEPART (dw, @date)-1), @ date) [dateTo]


0

사용자 지정 날짜로 시작 날짜 및 종료 날짜 가져 오기


   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]


이 코드는 질문을 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 도움이됩니다.
Shree

0

다른 방법이 있습니다. 현재 시작일과 요일 종료일을 선택합니다.

DATEADD (d,-(DATEPART (dw, GETDATE ()-2)), GETDATE ())는 날짜 시간입니다.

DATEADD (day, 7- (DATEPART (dw, GETDATE ()-1)), GETDATE ())는 날짜 시간입니다.


0

이를 수행하는 또 다른 방법 :

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는 최초 달력 날짜 ' 1900-01-01 ' 이후의 주 번호 입니다. 다음과 같이 계산할 수 있습니다.select datediff(week, 0, @wedding_date) as week_number
  • 주 첫날의 @start_weekday : 월요일의 경우 0 , 일요일의 경우 -1
  • 주 동안 @end_weekday 마지막 날 : 6 다음 일요일에, 5 의 경우 토요일
  • dateadd(week, @week_number, @end_weekday): 주어진 주 수와 주어진 일 수를 초기 달력 날짜 ' 1900-01-01 '에 추가합니다.

0

이것은 나에게서 온 것이 아니지만 상관없이 작업을 완료했습니다.

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

여기 에서 찾았습니다 .


-3

이것이 얼마나 유용한 지 확실하지 않지만 Netezza SQL에서 솔루션을 찾고 여기에 왔고 스택 오버플로에서 하나를 찾을 수 없었습니다.

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

WeekStart로 next_day (WeddingDate, 'SUN') -6을 선택합니다.

next_day (WeddingDate, 'SUN')를 WeekEnd로


-4

액세스 쿼리의 경우 필드로 아래 형식으로 사용할 수 있습니다.

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

직접 계산 가능 ..

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.