SQL Server - Получить первую дату за неделю, учитывая номер недели? - PullRequest
4 голосов
/ 26 июля 2010

У меня есть запрос (для использования в bug tracker.net), который подсчитывает количество ошибок по неделям по статусу. Но запрос возвращает номер недели, то, что я действительно хочу, это первая дата недели

select datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date)))
       as [week], bg_status , st_name as [status], count(*) as [count] 
  from bugs inner join statuses on bg_status = st_id 
 group by datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date))),
          bg_status, st_name
 order by [week], bg_status

Часть, которая получает номер недели:

datepart(wk, DateAdd(day, 0, DateDiff(day, 0, bg_reported_date))) as [week]

Возвращает этот вывод:

week        bg_status   status                                        count
----------- ----------- --------------------------------------------- ------
22          1           new                                           1
22          5           closed                                        32

Но было бы лучше сказать первое число каждой недели, например, 01-01-2010, затем 08-01-2010 и т. Д.

Вопрос не является дубликатом Как вы получаете "дату начала недели" и "дату конца недели" из номера недели в SQL Server? (в ответе указано, как начать неделю с даты с номера недели)

Не дубликат Рассчитать дату по номеру недели (вопрос требует c #)

Не дубликат Получить первую дату недели с указанной даты (вопрос требует JavaScript)

Я выполнил поиск, но не смог найти ответ на этот вопрос для SQL Server (2010, если это имеет значение)

Ответы [ 2 ]

5 голосов
/ 26 июля 2010

Если вы думаете об этом правильно, ответ на SO 1267126 может быть применен к вашей проблеме.

Каждая из указанных дат ошибок в картах группна той же неделе.Поэтому по определению каждая из этих дат ошибок также должна отображаться на одно и то же начало недели.Таким образом, вы запускаете вычисление «начало недели с заданной даты» для дат отчета об ошибках, а также вычисление номера недели и группируете их по обоим (скромно страшным) выражениям, и в итоге получаете искомый ответ.

SELECT DATEPART(wk, DATEADD(day, 0, DATEDIFF(d, 0, bg_reported_date))) [week],
       DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1), bg_reported_date)
       AS [weekstart], bg_status, st_name AS [status], COUNT(*) AS [count] 
  FROM bugs INNER JOIN statuses ON bg_status = st_id 
 GROUP BY DATEPART(wk, DATEADD(day, 0, DATEDIFF(day, 0, bg_reported_date))),
       DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1), bg_reported_date),
       bg_status, st_name
 ORDER BY [week], bg_status

Поскольку bg_reported_date - это DATETIME (см. Комментарий; он включает компонент времени), необходимо привести его к DATE, прежде чем определять начало недели (но выражение номера недели нене требуется приведение, и выражение начала недели «день недели» также не нуждается в приведении):

SELECT DATEPART(wk, DATEADD(day, 0, DATEDIFF(d, 0, bg_reported_date))) [week],
       DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1),
               CAST(bg_reported_date AS DATE)) AS [weekstart],
       bg_status, st_name AS [status], COUNT(*) AS [count] 
  FROM bugs INNER JOIN statuses ON bg_status = st_id 
 GROUP BY DATEPART(wk, DATEADD(day, 0, DATEDIFF(day, 0, bg_reported_date))),
       DATEADD(dd, -(DATEPART(dw, bg_reported_date)-1),
               CAST(bg_reported_date AS DATE),
       bg_status, st_name
 ORDER BY [week], bg_status

Примечание: непроверенный код!

0 голосов
/ 24 июля 2015

Я понимаю, что это очень старая ветка, но "Получить первое свидание за неделю, учитывая номер недели" - это именно то, что я хотел сделать, и у меня нет фактической даты для работы, поэтому принятый ответ будетне работа для меня.Я думал, что выложу свое решение для потомков.Обратите внимание, что я подозреваю, что различные настройки культуры МОГУТ это нарушить, поэтому тестируйте перед использованием.

Мой ответ строится начиная с this one.

Предположим, вы знаете номер неделии год, и вы хотите получить даты начала и окончания этой недели этого года.Вот что у меня есть:

--These 2 "declared" variables would be passed in somehow
declare @WeekNumber int = DATEPART(wk, GETDATE())
declare @ForYear int = YEAR(GETDATE())-1

--Since we don't have a raw date to work with, I figured I could just start with 
--Jan 1 of that year.  I'll store that date in a cte here, but if you are doing this
--in a stored proc or function, it would make much more sense to use another @variable
;with x as
(
    --this method works in SQL 2008:
    SELECT CONVERT(DateTime, ('1/1/' + CONVERT(varchar, @ForYear))) as Jan1ForSelectedYear
    --If you are using 2014 or higher, you can use this instead:
    --DATETIME2FROMPARTS(@ForYear, 1, 1, 0,0,0,0,0)
)
--Now that we have a date to work with, we'll just add the number of weeks to that date
--That will bring us to the right week number of the given year.
--Once we have THAT date, we can get the beginning and ending of that week
--Sorry to make you scroll, but I think this is easier to see what is going on this way
SELECT  CONVERT(varchar(50), DateAdd(wk, (@WeekNumber - 1), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, x.Jan1ForSelectedYear) - 6, x.Jan1ForSelectedYear))), 101) as FirstDayOfWeekXForSelectedYear,
        CONVERT(varchar(50), DateAdd(wk, (@WeekNumber - 1), (DATEADD(dd, @@DATEFIRST - DATEPART(dw, x.Jan1ForSelectedYear)    , x.Jan1ForSelectedYear))), 101) as LastDayOfWeekXForSelectedYear
FROM x
...