Предыдущий понедельник и предыдущая дата воскресенья на основе сегодняшней даты - программирование
Подтвердить что ты не робот

Предыдущий понедельник и предыдущая дата воскресенья на основе сегодняшней даты

Мне нужен правильный синтаксис, чтобы дать мне:

  1. Предыдущая неделя Дата понедельника на основе текущей даты/времени с использованием GETDATE()
  2. Дата воскресенья на предыдущей неделе, основанная на текущей дате/времени с использованием GETDATE()

Итак, исходя из сегодняшней даты (14/09/2012) я бы хотел следующее:

  1. Дата предыдущего понедельника = 03/09/2012
  2. Дата предыдущего воскресенья = 09/09/2012
4b9b3361

Ответ 1

Легко:

--start of last week
SELECT DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 0)

--end of last week
SELECT DATEADD(wk, DATEDIFF(wk, 6, GETDATE()), 6)

ИЗМЕНИТЬ

Ниже приведена проблема с датой в воскресенье.

DECLARE @input varchar(10)
--SET @input = '9/9/2012' -- simulates a Sunday
SET @input = GETDATE()

--start of last week
SELECT DATEADD(wk, DATEDIFF(wk, 6, 
CASE DATEPART(dw,@input)
WHEN 1 THEN DATEADD(d,-1,@input)
ELSE @input
END
), 0)

--end of last week
SELECT DATEADD(wk, DATEDIFF(wk, 6, 
CASE DATEPART(dw,@input)
WHEN 1 THEN DATEADD(d,-1,@input)
ELSE @input
END
), 6)

Ответ 2

Вместо использования опции case вы также можете сделать это, чтобы получить текущую неделю в воскресенье:

SELECT DATEADD(dd, DATEPART(DW,GETDATE())*-1+1, GETDATE())

Чтобы получить предыдущую неделю в воскресенье, вычтите еще 7 дней:

SELECT DATEADD(dd, DATEPART(DW,GETDATE())*-1-6, GETDATE())

Ответ 3

Я думаю, что это намного более чистое решение:

SELECT
    -- 17530101 or 1753-01-01 is the minimum date in SQL Server
    DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 7, '17530101') AS [LowerLimit], -- Last Week Monday
    DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 1, '17530101') AS [UpperLimit] -- Last Week Sunday.

Что можно использовать в реальном мире:

SELECT
    *
FROM
    SomeTable
WHERE
    SomeTable.[Date] >= DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 7, '17530101') AND
    SomeTable.[Date] <= DATEADD(dd, ((DATEDIFF(dd, '17530101', GETDATE()) / 7) * 7) - 1, '17530101')

Вот несколько тестов:

1. Високосный год

Текущая дата: 2016-02-29 00:00:00.000

Результаты:

LowerLimit                 UpperLimit
2016-02-22 00:00:00.000    2016-02-28 00:00:00.000

2. Последняя неделя была в разном году

Текущая дата: 2016-01-06 00:00:00.000

LowerLimit                 UpperLimit
2015-12-28 00:00:00.000    2016-01-03 00:00:00.000

3. Нижний предел в предыдущем месяце и верхний предел в текущем месяце

Текущая дата: 2016-05-04 00:00:00.000

LowerLimit                 UpperLimit
2016-04-25 00:00:00.000    2016-05-01 00:00:00.000

4. Текущая дата - воскресенье

Текущая дата: 2016-05-08 00:00:00.000

LowerLimit                 UpperLimit
2016-04-25 00:00:00.000    2016-05-01 00:00:00.000

Ответ 4

Еще лучше, я думаю, это работает для любой даты, любого дня недели, с любым параметром DateFirst (установите первый день недели, обычно 1-понедельник во Франции, по умолчанию - 7-воскресенье).

create function [dbo].[previousWeekDayDate](@anyDate date, @anyWeekDay int)
returns Date
as
begin
    return DATEADD(dd, ((DATEPART(dw,@anyDate) + @@DateFirst - @anyWeekDay + 13) % 7) * -1, @anyDate)
end

работает для SQL 2008, создайте функцию и используйте:

SELECT dbo.previousWeekDayDate(GetDate(),1) --for Monday
SELECT dbo.previousWeekDayDate(GetDate(),7) --for Sunday

Ответ 5

Следует отметить, что проблема с воскресеньями, по-видимому, больше не присутствует по крайней мере на MSSQL 2012. Как простое решение

SELECT DATEADD(wk, DATEDIFF(wk, 6, @input), 0)

и комплексный

SELECT DATEADD(wk, DATEDIFF(wk, 6, 
CASE DATEPART(dw,@input)
WHEN 1 THEN DATEADD(d,-1,@input)
ELSE @input
END
), 0)

верните то же самое для любой даты, которую я пробовал, включая воскресенья.

Ответ 6

Предыдущий понедельник:

SELECT DATEADD(DD,-(DATEPART(WEEKDAY, GETDATE())+5)%7, GETDATE())

Предыдущее воскресенье:

SELECT DATEADD(DD,-(DATEPART(WEEKDAY, GETDATE())+6)%7, GETDATE())