Obtenir le jour de la semaine dans SQL Server 2005/2008


369

Si j'ai une date 01/01/2009, je veux savoir quel jour c'était par exemple lundi, mardi, etc ...

Existe-t-il une fonction intégrée pour cela dans SQL Server 2005/2008? Ou dois-je utiliser une table auxiliaire?


1
Si vous avez un tableau contenant des recherches de parties de date, vous avez généralement fait quelque chose de mal. Les fonctions de date de SQL Server sont nombreuses et robustes, de sorte que toutes les données que vous devez extraire d'une date peuvent être facilement effectuées sur une colonne datetime.
Benjamin Autin

6
les tables auxiliaires sont très utiles pour les calculs de date, il n'est pas rare d'avoir une table auxiliaire de calendrier ...

2
"Utile pour les calculs de date" est très douteux. La plupart des calculs de date peuvent être traités sans aucun type de table auxiliaire et fonctionnent également mieux. Dans certains cas, une table de nombres simple fera le travail - pas besoin d'une table avec des dates réelles. La seule raison pour laquelle j'ai vu qu'un tableau de calendrier réel est nécessaire, c'est lorsque les règles pour lesquelles les jours sont des jours ouvrables et les jours qui ne le sont pas sont très compliquées. Ce que j'ai vu bien trop souvent, ce sont des gens qui utilisent des tableaux de dates parce qu'ils ne savent pas comment faire autrement. Ensuite, ils doivent remplir le tableau des dates de temps en temps. Idiot.
ErikE

5
Je vais manger mes mots si vous pouvez me montrer une utilisation pour les tableaux de calendrier qui 1) n'est pas pour les règles complexes de jour férié / journée de travail, 2) ne peut pas être fait facilement avec des fonctions intégrées, et 3) seulement si ce n'est pas le cas # 2, une table Numbers fonctionne aussi bien et ne nécessite pas de remplir la table avec des dates spécifiques.
ErikE

2
Les entrepôts de données utilisent largement les tableaux de calendrier. Les mois, trimestres, années, etc. précalculés fournissent aux utilisateurs finaux des champs sur lesquels ils peuvent filtrer / agréger.
David Rushton

Réponses:


694

Utilisez DATENAMEou DATEPART:

SELECT DATENAME(dw,GETDATE()) -- Friday
SELECT DATEPART(dw,GETDATE()) -- 6

thx, j'avais essayé datename mais utilisé d, m'a donné un entier. dw fonctionne comme prévu

39
C'est pourquoi je préfère utiliser select datename (en semaine, getdate ()). Je n'ai pas à me rappeler que dw retourne en semaine .... quand je peux utiliser "semaine" à la place.
George Mastros

9
quiconque y jette un œil - notez que le début de semaine par défaut est dimanche . Regardez la réponse de @ Sung pour savoir comment changer cela en toute sécurité
JonnyRaa

2
@niico c'est parce que les index SQL à partir de 1 tandis que les langages comme C indexent à partir de 0.
user824276

95

Même si la réponse de SQLMenace a été acceptée, il existe une SEToption importante que vous devez connaître

FIXER DATEFIRST

DATENAME renverra le nom de date correct mais pas la même valeur DATEPART si le premier jour de la semaine a été modifié comme illustré ci-dessous.

declare @DefaultDateFirst int
set @DefaultDateFirst = @@datefirst
--; 7 First day of week is "Sunday" by default
select  [@DefaultDateFirst] = @DefaultDateFirst 

set datefirst @DefaultDateFirst
select datename(dw,getdate()) -- Saturday
select datepart(dw,getdate()) -- 7

--; Set the first day of week to * TUESDAY * 
--; (some people start their week on Tuesdays...)
set datefirst 2
select datename(dw,getdate()) -- Saturday
--; Returns 5 because Saturday is the 5th day since Tuesday.
--; Tue 1, Wed 2, Th 3, Fri 4, Sat 5
select datepart(dw,getdate()) -- 5 <-- It's not 7!
set datefirst @DefaultDateFirst

33
Donc, pour obtenir une valeur de partie de date constante, vous le faites ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Le dimanche sera toujours nul.
Endy Tjahjono

1
horrible ce genre de choses est statique, vous devez donc suivre l'original de la requête, modifier la valeur, exécuter la requête, réinitialiser le modèle d'origine
JonnyRaa

2
Drôle de ceci est que de .NET DayOfWeekl'énumération a DayOfWeek.Sundayune valeur de ... 0. Ainsi, quel que DateFirstsoit le paramètre défini, une valeur renvoyée par SQL non traitéeWEEKDAY ne sera jamais compatible avec l'homologue .NET. Oui, Microsoft.
Eric Wu

26
SELECT  CASE DATEPART(WEEKDAY,GETDATE())  
    WHEN 1 THEN 'SUNDAY' 
    WHEN 2 THEN 'MONDAY' 
    WHEN 3 THEN 'TUESDAY' 
    WHEN 4 THEN 'WEDNESDAY' 
    WHEN 5 THEN 'THURSDAY' 
    WHEN 6 THEN 'FRIDAY' 
    WHEN 7 THEN 'SATURDAY' 
END

26
Vous devez savoir qu'il existe une fonction intégrée pour obtenir le même résultat. select datename(dw,getdate())
Soham Dasgupta

10
@SohamDasgupta cette fonction intégrée ne renvoie pas le même résultat pour la version non anglaise de MS SQL.
M. Scapegrace

12

Pour obtenir une valeur déterministe pour le jour de la semaine pour une date donnée, vous pouvez utiliser une combinaison de DATEPART () et @@ datefirst . Sinon, vous dépendez des paramètres du serveur.

Consultez le site suivant pour une meilleure solution: MS SQL: jour de la semaine

Le jour de la semaine sera alors compris entre 0 et 6, où 0 est le dimanche, 1 le lundi, etc. Vous pouvez ensuite utiliser une simple déclaration de casse pour renvoyer le nom de jour de semaine correct.


5
Veuillez mettre la réponse dans la réponse afin que les gens n'aient pas à cliquer sur un lien pour y accéder.
Martin Smith

11

L'EUROPE :

declare @d datetime;
set @d=getdate();
set @dow=((datepart(dw,@d) + @@DATEFIRST-2) % 7+1);

2
Veuillez inclure une explication de ce que fait votre code et comment il répond à la question. Si vous obtenez un extrait de code comme réponse, vous ne savez peut-être pas quoi en faire. La réponse doit donner au PO et aux futurs visiteurs des conseils sur la façon de déboguer et de résoudre leur problème. Indiquer quelle est l'idée derrière votre code aide grandement à comprendre le problème et à appliquer ou modifier votre solution.
Palec

6

Avec SQL Server 2012 et versions ultérieures, vous pouvez utiliser la FORMATfonction

SELECT FORMAT(GETDATE(), 'dddd')

3

ceci est une copie de travail de mon code, vérifiez comment récupérer le nom du jour à partir de la date en sql

CREATE Procedure [dbo].[proc_GetProjectDeploymentTimeSheetData] 
@FromDate date,
@ToDate date

As 
Begin
select p.ProjectName + ' ( ' + st.Time +' '+'-'+' '+et.Time +' )' as ProjectDeatils,
datename(dw,pts.StartDate) as 'Day'
from 
ProjectTimeSheet pts 
join Projects p on pts.ProjectID=p.ID 
join Timing st on pts.StartTimingId=st.Id
join Timing et on pts.EndTimingId=et.Id
where pts.StartDate >= @FromDate
and pts.StartDate <= @ToDate
END

1

Si vous ne voulez pas dépendre @@DATEFIRSTou utiliser DATEPART(weekday, DateColumn), calculez simplement le jour de la semaine vous-même.

Pour les semaines du lundi (Europe), la plus simple est:

SELECT DATEDIFF(day, '17530101', DateColumn) % 7 + 1 AS MondayBasedDay

Pour les semaines du dimanche (Amérique), utilisez:

SELECT DATEDIFF(day, '17530107', DateColumn) % 7 + 1 AS SundayBasedDay

Cela renvoie le numéro de semaine (1 à 7) depuis le 1er janvier respectivement le 7 1753.


1

Vous pouvez utiliser, DATEPART(dw, GETDATE())mais sachez que le résultat dépendra de la @@DATEFIRSTvaleur de paramètre du serveur SQL qui est le premier jour de la semaine (en Europe, la valeur par défaut 7, qui est le dimanche).

Si vous souhaitez remplacer le premier jour de la semaine par une autre valeur, vous pouvez l'utiliser, SET DATEFIRSTmais cela peut affecter partout dans votre session de requête ce que vous ne souhaitez pas.

Une autre méthode consiste à spécifier explicitement la valeur du premier jour de la semaine comme paramètre et à éviter de dépendre du @@DATEFIRSTréglage. Vous pouvez utiliser la formule suivante pour y parvenir en cas de besoin:

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

@WeekStartDayest le premier jour de la semaine que vous souhaitez pour votre système (de 1 à 7 ce qui signifie du lundi au dimanche).

Je l'ai enveloppé 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)

Il est équivalent à ce qui suit (mais indépendant du paramètre DATEFIRST du serveur SQL):

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

0

Vous pouvez trouver cette version utile.

-- Test DATA
select @@datefirst
create table #test (datum datetime)
insert #test values ('2013-01-01')
insert #test values ('2013-01-02')
insert #test values ('2013-01-03')
insert #test values ('2013-01-04')
insert #test values ('2013-01-05')
insert #test values ('2013-01-06')
insert #test values ('2013-01-07')
insert #test values ('2013-01-08')
-- Test DATA

select  Substring('Sun,Mon,Tue,Wed,Thu,Fri,Sat,Sun,Mon,Tue,Wed,Thu,Fri,Sat',
        (DATEPART(WEEKDAY,datum)+@@datefirst-1)*4+1,3),Datum
        from #test 

1
Ce code est obtus et ne donne aucune indication de ce qu'il fait ou essaie de réaliser
brewmanz
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.