Получить последнюю пятницу Дата, если сегодня пятница с использованием T-SQL

Я пытаюсь получить правильный код SQL, чтобы получить последнюю пятницу. Несколько дней назад я думал, что у меня правильный код. Но только что заметил, что он получал последнюю пятницу в пятницу, а не в прошлую пятницу. В тот день, когда я пишу этот вопрос, суббота, 8/11/2012 @12:23. В SQL Server этот код возвращается в пятницу, 8/3/2012. Тем не менее, я хочу, чтобы это вернулось в пятницу, 8/10/2012. Как я могу исправить этот код? Поскольку мы добираемся до специфики здесь, если текущий день - пятница, то я хочу вернуться сегодня. Так что если вчера (8/10/2012) и я вчера запустил этот код, я бы хотел, чтобы этот код возвращался 8/10/2012, а не 8/3/2012.

SELECT DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, GETDATE()), 0))

Ответ 1

попробуйте следующее:

declare @date datetime;
set @date='2012-08-09'
SELECT case when datepart(weekday, @date) >5 then
 DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) 
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) end

результат

2012-08-03 

Пример 2:

declare @date datetime;
set @date='2012-08-10'
SELECT case when datepart(weekday, @date) >5 then
 DATEADD(DAY, +4, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) 
else DATEADD(DAY, -3, DATEADD(WEEK, DATEDIFF(WEEK, 0, @date), 0)) end

результат

  2012-08-10 

Ответ 2

Модульная арифметика - это самый прямой подход, и порядок операций решает, как обрабатываются пятницы:

DECLARE @test_date DATETIME = '2012-09-28'

SELECT DATEADD(d,-1-(DATEPART(dw,@test_date) % 7),@test_date) AS Last_Friday
      ,DATEADD(d,-(DATEPART(dw,@test_date+1) % 7),@test_date) AS This_Friday

Ответ 3

Используйте это:

SELECT DATEADD(day, (DATEDIFF (day, '19800104', CURRENT_TIMESTAMP) / 7) * 7, '19800104') as Last_Friday

Ответ 4

Проверенная функция, которая работает независимо от того, для чего установлен @@DATEFIRST.

-- ==============
-- fn_Get_Week_Ending_forDate
-- Author:      Shawn C. Teague
-- Create date: 2017
-- Modified date:  
-- Description:   Returns the Week Ending Date on DayOfWeek for a given stop date
-- Parameters: DayOfWeek varchar(10) i.e. Monday,Tues,Wed,Friday,Sat,Su,1-7
--             DateInWeek DATE
-- ==============
CREATE FUNCTION [dbo].[fn_Get_Week_Ending_forDate] (
                   @DayOfWeek VARCHAR(10),@DateInWeek DATE)
RETURNS DATE
AS
BEGIN
   DECLARE @End_Date DATE
          ,@DoW TINYINT
   SET @DoW = CASE WHEN ISNUMERIC(@DayOfWeek) = 1 
                     THEN CAST(@DayOfWeek AS TINYINT)
                  WHEN @DayOfWeek like 'Su%' THEN 1
                  WHEN @DayOfWeek like 'M%'  THEN 2
                     WHEN @DayOfWeek like 'Tu%' THEN 3
                  WHEN @DayOfWeek like 'W%'  THEN 4
                  WHEN @DayOfWeek like 'Th%' THEN 5
                  WHEN @DayOfWeek like 'F%'  THEN 6
                  ELSE  7
               END

   select @End_Date = 
          CAST(DATEADD(DAY,
               CASE WHEN (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7)) = 7
                        THEN 0 
                    WHEN (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7)) < 0 
                        THEN 7 - ABS(@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7))
                    ELSE (@DoW - (((@@datefirst) + datepart(weekday, @DateInWeek)) % 7) ) 
               END
               ,@DateInWeek) AS DATE)

   RETURN @End_Date
END

Ответ 5

Это даст вам пятницу на прошлой неделе.

SELECT DATEADD(day, -3 - (DATEPART(dw, GETDATE()) + @@DATEFIRST - 2) % 7, GETDATE()) AS LastWeekFriday

Это даст вам последнюю пятницу.

SELECT DATEADD(day, +4 - (DATEPART(dw, GETDATE()) + @@DATEFIRST-2) % 7, GETDATE()) AS LastFriday

Ответ 6

select convert(varchar(10),dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate()),101)

Ответ 7

Следующий код можно использовать для возврата в любой последний день, заменив @dw_wk, тестовый пример ниже используется в пятницу, как задано в исходных вопросах.

DECLARE @date SMALLDATETIME
,@dw_wk INT --last day of week required - its integer representation
,@dw_day int --current day integer reprsentation
SELECT @date='8/11/2012'
SELECT @dw_day=DATEPART(dw,@date)
SELECT @dw_wk=DATEPART(dw,'1/2/2015') --Just trying not to hard code 5 for friday, here we can substitute with any date which is friday
SELECT case when @dw_day<@dw_wk then DATEADD(DAY, @[email protected]_day,@date) else DATEADD(DAY,@[email protected]_day, @date) END

Ответ 8

Вот ответ, который я нашел здесь, адаптированный от MySQL к T-SQL, который является одним лайнером, используя всю базовую арифметику (без деления или модуля ):

SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 2, GETDATE())), GETDATE())

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

Получить следующую пятницу, если сегодня не пятница

SELECT DATEADD(d, 7 - datepart(weekday, dateadd(d, 1, GETDATE())), GETDATE())

Получить последний четверг, если сегодня не четверг

SELECT DATEADD(d, 1 - datepart(weekday, dateadd(d, 3, GETDATE())), GETDATE())

Ответ 9

SELECT DECODE(TO_CHAR(SYSDATE,'DY'),'FRI',SYSDATE,NEXT_DAY(SYSDATE, 'FRI')-7) FROM dual; 

Ответ 10

У меня была такая же проблема, и я создал следующий пример, чтобы показать, как это сделать, и сделать его гибким, чтобы использовать тот день недели, который вы хотите. У меня разные строки в инструкции SELECT, чтобы показать, что это делает, но вам нужна строка [Results], чтобы получить ответ. Я также использовал переменные для текущей даты и целевого дня недели, чтобы было легче увидеть, что нужно изменить.

Наконец, есть пример результатов, когда вы хотите включить текущую дату в качестве возможного примера или когда вы всегда хотите вернуться к предыдущей неделе.

DECLARE @GetDate AS DATETIME = GETDATE();
DECLARE @Target INT = 6 -- 6 = Friday

SELECT
        @GetDate                                                                                                                                AS [Current Date]       ,
        DATEPART(dw, @GetDate)                                                                                                                  AS [Current Day of Week],
        @Target                                                                                                                                 AS [Target Day of Week] ,
             IIF(@Target = DATEPART(dw, @GetDate), 'Yes'   , 'No')                                                                              AS [IsMatch]            ,
             IIF(@Target = DATEPART(dw, @GetDate), 0       ,               ((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7)                    AS [DateAdjust]         ,
      ------------------------------------------------------------------------------------------------------------------------------------------------
        CAST(IIF(@Target = DATEPART(dw, @GetDate), @GetDate, DATEADD(d, (((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7), @GetDate)) AS DATE) AS [Result]
      ------------------------------------------------------------------------------------------------------------------------------------------------
;
SELECT
        @GetDate                                                                               AS [Current Date]       ,
        DATEPART(dw, @GetDate)                                                                 AS [Current Day of Week],
        @Target                                                                                AS [Target Day of Week] ,
                           ((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7                    AS [DateAdjust]         ,
      ------------------------------------------------------------------------------------------------------------------------------------------------
        CAST(DATEADD(d, (((7 + @Target - DATEPART(dw, @GetDate)) % 7) - 7), @GetDate) AS DATE) AS [NOTIncludeCurrent]
      ------------------------------------------------------------------------------------------------------------------------------------------------
;