web-dev-qa-db-fra.com

Obtenez la date du dernier vendredi à moins qu'aujourd'hui ne soit vendredi en utilisant T-SQL

J'essaie d'obtenir le code SQL correct pour obtenir la date de vendredi dernier. Il y a quelques jours, je pensais que mon code était correct. Mais je viens de remarquer qu'il s'agit de la date du vendredi de la semaine dernière, pas du dernier vendredi. Le jour où j'écris cette question est le samedi 8/11/2012 à 00h23. Dans SQL Server, ce code revient le vendredi 8/3/2012. Cependant, je veux que cela revienne le vendredi 8/10/2012 à la place. Comment puis-je corriger ce code? Étant donné que nous arrivons à des détails ici, si le jour en cours est vendredi, je veux revenir à la date d'aujourd'hui. Donc, si c'était hier (8/10/2012) et que j'ai exécuté ce code hier, je voudrais que ce code renvoie le 8/10/2012, pas le 8/3/2012.

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

essaye ça:

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

résultat:

2012-08-03 

Exemple2:

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

résultat:

  2012-08-10 
13
Joe G Joseph

L'arithmétique modulaire est l'approche la plus directe, et l'ordre des opérations décide de la façon dont les vendredis sont traités:

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
9
Michael

Utilisez ceci :

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

Une fonction testée qui fonctionne quelle que soit la valeur de @@ 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
2
Shawn Teague

Rien de cela? Essaye ça:

DECLARE @D DATE = GETDATE()
SELECT DATEADD(D,-(DATEPART(W,@D)+1)%7,@D)
2
Cory

Cela vous donnera le vendredi de la semaine dernière.

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

Cela vous donnera la date de vendredi dernier.

SELECT DATEADD(day, +4 - (DATEPART(dw, GETDATE()) + @@DATEFIRST-2) % 7, GETDATE()) AS LastFriday
1
Krishna Thota
SELECT DECODE(TO_CHAR(SYSDATE,'DY'),'FRI',SYSDATE,NEXT_DAY(SYSDATE, 'FRI')-7) FROM dual; 
1
Md Sultan

Le code suivant peut être utilisé pour retourner n'importe quel dernier jour en remplaçant @dw_wk, le cas de test ci-dessous utilise vendredi comme demandé dans les questions originales

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, @dw_wk-7-@dw_day,@date) else DATEADD(DAY,@dw_wk-@dw_day, @date) END
1
Nakul Manchanda

Voici une réponse que j'ai trouvée ici adapté de MySQL à T-SQL qui est un liner utilisant toute l'arithmétique de base (pas de division ou de modules):

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

Vous pouvez faire toutes sortes de combinaisons de cela, comme obtenir la date de vendredi prochain à moins qu'aujourd'hui soit vendredi, ou obtenir la date de jeudi dernier à moins qu'aujourd'hui soit jeudi en changeant simplement le 1 et les 2 littéraux dans la commande:

Obtenez la date du vendredi suivant, à moins qu'aujourd'hui ne soit vendredi

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

Obtenez la date de jeudi dernier à moins qu'aujourd'hui soit jeudi

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

J'ai eu ce même problème et j'ai créé l'exemple suivant pour montrer comment procéder et pour le rendre flexible à utiliser quel que soit le jour de la semaine que vous souhaitez. J'ai différentes lignes dans l'instruction SELECT, juste pour montrer ce que cela fait, mais vous avez juste besoin du [Results] ligne pour obtenir la réponse. J'ai également utilisé des variables pour la date actuelle et le jour cible de la semaine, afin de voir plus facilement ce qui doit changer.

Enfin, il existe un exemple de résultats lorsque vous souhaitez inclure la date actuelle comme exemple possible ou lorsque vous souhaitez toujours revenir à la semaine précédente.

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]
      ------------------------------------------------------------------------------------------------------------------------------------------------
;
1
RPh_Coder
select convert(varchar(10),dateadd(d, -((datepart(weekday, getdate()) + 1 + @@DATEFIRST) % 7), getdate()),101)
1
Dishant Daryani