web-dev-qa-db-fra.com

Comment définir le lundi comme premier jour de la semaine dans SQL Server

J'exécute SQL Server 2008 sur une machine avec des paramètres régionaux dont le lundi est le premier jour de la semaine. Si je crée une colonne calculée dans une table pour calculer le jour de la semaine pour un champ de date, je reçois 2 pour une date de lundi au lieu de 1.

Existe-t-il une propriété pour la table, la base de données ou le serveur que je dois définir?

12
Clipper87

Le premier jour de la semaine est basé sur les paramètres de langue du serveur. Le paramètre par défaut pour us_english est 7 (dimanche).

Vous pouvez trouver le premier jour de la semaine en cours à l’aide de SELECT @@DATEFIRST


Cependant, vous pouvez utiliser DATEFIRST pour cela. Il suffit de le mettre en haut de votre requête

SET DATEFIRST 1; définit le lundi sur le premier jour de la semaine pour la connexion en cours.

http://technet.Microsoft.com/en-us/library/ms181598.aspx

22
Sam

Juste mis en requête

SET DATEFIRST 1;

Valeur Le premier jour de la semaine est 1 lundi 2 mardi 3 mercredi 4 jeudi 5 vendredi 6 samedi 7 (par défaut, anglais américain) dimanche

4
Coder

Une situation horrible .... Supposons que vous utilisez un serveur partagé et que les applications peuvent être déplacées vers différents serveurs en fonction de leur charge. Pour une raison quelconque, un serveur a été configuré avec une première date différente pour une autre application .... et vous renvoyez le jour de la semaine dans une fonction de table (c.-à-d. impossible de définir la première date dans cette fonction). Cela garantira toujours le lundi comme premier jour.

CREATE FUNCTION fnGetMondayWD(@WD INT)
RETURNS INT
AS
     BEGIN

         /* think of 1 to 7 as a clock that can rotate forwards or backwards */

         DECLARE @OFFSET INT, @calc INT;
         SET @offset = @@DATEFIRST + @WD - 1;--Monday DateFirst
         SET @calc = IIF(@offset > 7, @offset - 7, @offset); -- could be @offset % 7 (less readable more efficient)
         RETURN @calc;
     END;

go

-- Test Cases


SET datefirst 7
select dbo.fnGetMondayWD(2) Mon,
     dbo.fnGetMondayWD(3)Tue, 
     dbo.fnGetMondayWD(4)Wed, 
     dbo.fnGetMondayWD(5)Thur, 
     dbo.fnGetMondayWD(6)Fri, 
     dbo.fnGetMondayWD(7)Sat, 
     dbo.fnGetMondayWD(1)Sun


SET datefirst 6
select dbo.fnGetMondayWD(3) Mon,
     dbo.fnGetMondayWD(4)Tue, 
     dbo.fnGetMondayWD(5)Wed, 
     dbo.fnGetMondayWD(6)Thur, 
     dbo.fnGetMondayWD(7)Fri, 
     dbo.fnGetMondayWD(1)Sat, 
     dbo.fnGetMondayWD(2)Sun

SET datefirst 5
select dbo.fnGetMondayWD(4) Mon,
     dbo.fnGetMondayWD(5)Tue, 
     dbo.fnGetMondayWD(6)Wed, 
     dbo.fnGetMondayWD(7)Thur, 
     dbo.fnGetMondayWD(1)Fri, 
     dbo.fnGetMondayWD(2)Sat, 
     dbo.fnGetMondayWD(3)Sun

SET datefirst 1
select dbo.fnGetMondayWD(1) Mon,
     dbo.fnGetMondayWD(2)Tue, 
     dbo.fnGetMondayWD(3)Wed, 
     dbo.fnGetMondayWD(4)Thur, 
     dbo.fnGetMondayWD(5)Fri, 
     dbo.fnGetMondayWD(6)Sat, 
     dbo.fnGetMondayWD(7)Sun
0
Donald Detelj

Vous pouvez utiliser DATEPART(dw, GETDATE()) mais sachez que le résultat dépendra du paramètre SQL Server @@DATEFIRST qui correspond au premier jour de la semaine (la valeur par défaut 7 pour l'Europe est dimanche).

Une autre méthode consiste à spécifier explicitement la valeur du premier jour de la semaine en tant que paramètre et à éviter de dépendre du paramètre @@DATEFIRST. Vous pouvez utiliser la formule suivante pour y parvenir lorsque vous en avez besoin:

(DATEPART(dw, GETDATE()) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1

@WeekStartDay est le premier jour de la semaine que vous souhaitez pour votre système (de 1 à 7, du lundi au dimanche).

Je l'ai emballé dans la fonction ci-dessous afin que nous puissions le réutiliser facilement:

CREATE FUNCTION [dbo].[GetDayInWeek](@InputDateTime DATETIME, @WeekStartDay INT)
RETURNS INT
AS
BEGIN
    --Note: @WeekStartDay is number from [1 - 7] which is from Monday to Sunday
    RETURN (DATEPART(dw, @InputDateTime) + @@DATEFIRST + 6 - @WeekStartDay) % 7 + 1 
END

Exemple d'utilisation: GetDayInWeek('2019-02-04 00:00:00', 1)

Cela équivaut à suivre (mais indépendamment du paramètre DATEFIRST): 

SET DATEFIRST 1
DATEPART(dw, '2019-02-04 00:00:00')
0
Minh Nguyen