Получение номера недели от даты в MS SQL Server 2005? - PullRequest
12 голосов
/ 08 декабря 2008

Можно ли создать SQL-оператор, который выбирает номер недели (НЕ день недели - или номер дня в неделе). Я создаю представление для выбора этой дополнительной информации вместе с парой других полей и, следовательно, не могу использовать хранимую процедуру. Я знаю, что для создания цели можно создать UDF, но если это вообще возможно, я бы предпочел только добавить представление в эту базу данных, а не только представление и функцию.

Есть идеи? Кроме того, откуда я родом, неделя начинается с понедельника, а неделя 1 - это первая неделя года, по крайней мере, 4 дня.

Связанный:

Как рассчитать номер недели с учетом даты?

Ответы [ 8 ]

18 голосов
/ 08 декабря 2008

Вам нужна неделя ISO. От http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=60510, вот реализация:

drop function dbo.F_ISO_WEEK_OF_YEAR
go
create function dbo.F_ISO_WEEK_OF_YEAR
    (
    @Date   datetime
    )
returns     int
as
/*
Function F_ISO_WEEK_OF_YEAR returns the
ISO 8601 week of the year for the date passed.
*/
begin

declare @WeekOfYear     int

select
    -- Compute week of year as (days since start of year/7)+1
    -- Division by 7 gives whole weeks since start of year.
    -- Adding 1 starts week number at 1, instead of zero.
    @WeekOfYear =
    (datediff(dd,
    -- Case finds start of year
    case
    when    NextYrStart <= @date
    then    NextYrStart
    when    CurrYrStart <= @date
    then    CurrYrStart
    else    PriorYrStart
    end,@date)/7)+1
from
    (
    select
        -- First day of first week of prior year
        PriorYrStart =
        dateadd(dd,(datediff(dd,-53690,dateadd(yy,-1,aa.Jan4))/7)*7,-53690),
        -- First day of first week of current year
        CurrYrStart =
        dateadd(dd,(datediff(dd,-53690,aa.Jan4)/7)*7,-53690),
        -- First day of first week of next year
        NextYrStart =
        dateadd(dd,(datediff(dd,-53690,dateadd(yy,1,aa.Jan4))/7)*7,-53690)
    from
        (
        select
            --Find Jan 4 for the year of the input date
            Jan4    = 
            dateadd(dd,3,dateadd(yy,datediff(yy,0,@date),0))
        ) aa
    ) a

return @WeekOfYear

end
go
18 голосов
/ 08 декабря 2008

Имейте в виду, что существуют различия в том, что считается правильным номером недели, в зависимости от культуры. Числа недели зависят от пары предположений, которые отличаются от страны к стране, см. статью Википедии по этому вопросу . Существует стандарт ISO (ISO 8601), который применяется к номерам недели.

Встроенная в SQL-сервер функция DATEPART() не обязательно выполняет правильные задачи. SQL Server предполагает, что 1-й день 1-й недели будет 1 января, для многих приложений это неправильно.

Правильный расчет номеров недель нетривиален, и в Интернете можно найти различные реализации. Например, есть UDF, который вычисляет номера недель ISO с 1930-2030 , являясь одним из многих других. Вам придется проверить, что работает для вас.

Это из Books Online (хотя вы, вероятно, захотите использовать тот из ответа Джонаса Линкольна , версия BOL, похоже, неверна):

CREATE FUNCTION ISOweek  (@DATE DATETIME)
RETURNS INT
AS
BEGIN
   DECLARE @ISOweek INT
   SET @ISOweek = DATEPART(wk,@DATE) 
                  +1 
                  -DATEPART(wk,CAST(DATEPART(yy,@DATE) AS CHAR(4))+'0104')
   -- Special cases: Jan 1-3 may belong to the previous year
   IF (@ISOweek=0)
      SET @ISOweek = dbo.ISOweek(CAST(DATEPART(yy,@DATE) - 1
                     AS CHAR(4))+'12'+ CAST(24+DATEPART(DAY,@DATE) AS CHAR(2)))+1
   -- Special case: Dec 29-31 may belong to the next year
   IF ((DATEPART(mm,@DATE)=12) AND
      ((DATEPART(dd,@DATE)-DATEPART(dw,@DATE))>= 28))
      SET @ISOweek=1
   RETURN(@ISOweek)
END
GO
4 голосов
/ 08 декабря 2008

Похоже, функция DATEPART mssql должна помочь вам с ...

DATEPART(wk, ‘Jan 1, xxxx’) = 1

Ну, я буду .. оказывается, есть способ установить первый день недели, DATEFIRST

SET DATEFIRST 1 -- for monday

Обновление : Теперь я лучше понимаю, чего хочет ОП .. какая именно логика для этого. Я не думаю, что MSSQL будет иметь функции с таким богатым уровнем настройки. Но я могу ошибаться ... Я думаю, что вам придется бросить свой собственный UDF здесь ... извините

2 голосов
/ 09 декабря 2015

ЗАБУДЬТЕ ДРУГИЕ ОТВЕТЫ

В вопросе указывается, что « неделя начинается с понедельника, а неделя 1 - это первая неделя года, по крайней мере, с 4 днями. » Это стандарт ISO 8601 и ответ на этот вопрос Эта функция используется в производстве на нашем сайте.

Это все, что вам нужно:

CREATE FUNCTION ISOweek  (@DATE DATETIME)
RETURNS INT
AS
BEGIN
    RETURN (datepart(DY, datediff(d, 0, @DATE) / 7 * 7 + 3)+6) / 7
END
GO
1 голос
/ 08 декабря 2008

Это вернет вам номер недели, указанный в кавычках

SELECT DATEPART( wk, 'enter the date over here' )
0 голосов
/ 11 августа 2016

Почему снова люди делают горы из кротов, меня это изумляет?

Так просто ...

select DATEPART(wk, GETDATE())
0 голосов
/ 08 декабря 2008

Рассматривали ли вы использовать функцию WEEK?

Это даст вам неделю года за указанную вами дату.

SELECT { fn WEEK(GETDATE()) } AS WeekNumber, { fn WEEK(CONVERT(DATETIME, '2008-01-01 00:00:00', 102)) } AS FirstWeekOfYear, { fn WEEK(CONVERT(DATETIME, '2008-12-31 00:00:00', 102)) } AS LastWeekOfYear

Это выводит следующие SQL2000 и SQL2005:

  • Номер недели: 50
  • FirstWeekOfYear: 1
  • LastWeekOfYear: 53

Надеюсь, это поможет:)

0 голосов
/ 08 декабря 2008

Похоже, datepart поможет вам в этом, но вам придется скорректировать, чтобы получить правильный номер недели, исходя из дня недели 1 января данного года. Я не достаточно знаком с T-SQL, чтобы сделать это, но это должно быть возможно. Жаль, что нет аргумента режима, как в MySQL

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...