Как получить "дату начала недели" и "дату окончания недели" из номера недели в SQL Server?
у меня есть запрос, который подсчитывает свадебные даты в базе данных...
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
13 ответов:
вы можете найти день недели и сделать дату добавить на дни, чтобы получить даты начала и окончания..
DATEADD(dd, -(DATEPART(dw, WeddingDate)-1), WeddingDate) [WeekStart] DATEADD(dd, 7-(DATEPART(dw, WeddingDate)), WeddingDate) [WeekEnd]вы, вероятно,также хотите посмотреть на снятие времени с даты, хотя.
здесь
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
вот еще одна версия. Если ваш сценарий требует, чтобы суббота была 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
ниже запрос даст данные между началом и концом текущей недели начиная с воскресенья по субботу
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())
расширения @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установка, которая является то, что мне нужно, как я строю из измерения даты с несколькими методами недели включены.
Давайте разделим проблему на две части:
1) Определите день недели
The
DATEPART(dw, ...)возвращает число, 1...7, относительноDATEFIRSTнастройка (docs). В следующей таблице приведены возможные значения:@@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 + 12) вычислить понедельник и воскресенье для данной даты
это тривиально благодаря значению дня недели. Вот пример:
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-27 и 2016-01-02, но правильный ответ 2016-01-01 и 2016-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-й или другие.
Это не пришло от меня, но это сделало работу:
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Я нашел его здесь.
дата начала и окончания недели с даты для Формулы DAX Power BI
WeekStartDate = [DateColumn] - (WEEKDAY([DateColumn])-1) WeekEndDate = [DateColumn] + (7-WEEKDAY([DateColumn]))
Не уверен, насколько это полезно, но я оказался здесь от поиска решения на Netezza SQL и не смог найти его в Stack overflow.
для IBM netezza вы бы использовали что-то (для недели start mon, week end sun), например:
выберите next_day (WeddingDate, 'SUN') -6 как WeekStart,
next_day (WeddingDate, 'SUN') как выходные
для запросов доступа, вы можете использовать в приведенном ниже формате в качестве поля
"FirstDayofWeek:IIf(IsDate([ForwardedForActionDate]),CDate(Format([ForwardedForActionDate],"dd/mm/yyyy"))-(Weekday([ForwardedForActionDate])-1))"прямой расчет допускается..


Comments