Ottieni il giorno della settimana in SQL Server 2005/2008


369

Se ho una data 01/01/2009, voglio scoprire che giorno è stato ad esempio lunedì, martedì, ecc ...

Esiste una funzione integrata per questo in SQL Server 2005/2008? O devo usare una tabella ausiliaria?


1
Se si dispone di una tabella contenente ricerche per le parti della data, in genere si è verificato un errore. Le funzioni di data di SQL Server sono numerose e affidabili, quindi tutti i dati che è necessario estrarre da una data possono essere prontamente eseguiti su una colonna datetime.
Benjamin Autin,

6
le tabelle ausiliarie sono molto utili per i calcoli della data, non è insolito disporre di una tabella ausiliaria del calendario ...

2
"Utile per i calcoli della data" è altamente dubbio. La maggior parte dei calcoli della data può essere gestita senza alcun tipo di tabella ausiliaria e funzionerà anche meglio. In alcuni casi, una semplice tabella Numbers farà il lavoro, senza bisogno di una tabella con le date effettive al suo interno. L'unica ragione per cui ho visto che è necessaria una tabella di calendario effettiva è quando le regole per quali giorni sono giorni lavorativi e quali giorni non lo sono sono molto complicate. Quello che ho visto troppo spesso sono le persone che usano le tabelle delle date perché non sanno come fare diversamente. Quindi devono popolare la tabella delle date ogni tanto. Silly.
ErikE,

5
Mangerò le mie parole se puoi mostrarmi un uso per le tabelle del calendario che 1) non è per le complesse regole ferie / giorni lavorativi, 2) non può essere fatto facilmente con le funzioni integrate e 3) solo se non # 2, quindi una tabella di numeri funziona altrettanto bene e non richiede di popolare la tabella con date specifiche.
ErikE,

2
I data warehouse fanno ampio uso delle tabelle del calendario. I mesi, i trimestri, gli anni, ecc. Precalcolati forniscono agli utenti finali i campi sui quali possono filtrare / aggregare.
David Rushton, il

Risposte:


694

Usa DATENAMEo DATEPART:

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

grazie, avevo provato a usare il nome, ma ho usato d, mi ha restituito un numero intero. dw funziona come previsto

39
Ecco perché preferisco usare select nomename (giorno della settimana, getdate ()). Non devo ricordare che dw ritorna nei giorni feriali .... quando invece posso usare "giorni feriali".
George Mastros,

9
chiunque dia un'occhiata a questo - si noti che l' inizio predefinito della settimana è domenica . Guarda la risposta di @ Sung su come cambiarla in modo sicuro
JonnyRaa

2
@niico è perché SQL indicizza da 1 mentre C come l'indice delle lingue da 0.
user824276

95

Anche se la risposta di SQLMenace è stata accettata, c'è SETun'opzione importante che dovresti conoscere

SET DATEFIRST

DATENAME restituirà il nome della data corretto ma non lo stesso valore DATEPART se il primo giorno della settimana è stato modificato come illustrato di seguito.

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
Quindi, per ottenere un valore costante di datepart, lo fai ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Domenica sarà sempre zero.
Endy Tjahjono,

1
un po 'orribile questa roba è statica, quindi devi seguire la query originale, modificare il valore, eseguire la query, ripristinare il modello originale
JonnyRaa

2
Parte divertente di questo è che di .NET DayOfWeekenumerazione ha DayOfWeek.Sundayun valore ... 0. Pertanto, indipendentemente da ciò che DateFirstviene impostato, un valore restituito da SQL non trattatoWEEKDAY non sarà mai compatibile con la controparte .NET. Sì, 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
Dovresti sapere che esiste una funzione integrata per ottenere lo stesso. select datename(dw,getdate())
Soham Dasgupta,

10
@SohamDasgupta questa funzione integrata non restituisce lo stesso risultato per la versione non inglese di MS SQL.
Scapegrace,

12

Per ottenere un valore deterministico per il giorno della settimana per una determinata data, è possibile utilizzare una combinazione di DATEPART () e @@ datefirst . Altrimenti dipende dalle impostazioni sul server.

Controlla il seguente sito per una soluzione migliore: MS SQL: giorno della settimana

Il giorno della settimana sarà quindi compreso nell'intervallo da 0 a 6, dove 0 è domenica, 1 è lunedì, ecc. Quindi è possibile utilizzare un'istruzione case semplice per restituire il nome del giorno della settimana corretto.


5
Inserisci la risposta nella risposta in modo che le persone non debbano fare clic su un link per accedervi.
Martin Smith,

11

EUROPA:

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

2
Includi la spiegazione di ciò che fa il tuo codice e di come risponde alla domanda. Se ricevi uno snippet di codice come risposta, potresti non sapere cosa farne. La risposta dovrebbe fornire all'OP e ai futuri visitatori indicazioni su come eseguire il debug e risolvere il problema. Sottolineando quale sia l'idea alla base del codice, aiuta notevolmente a comprendere il problema e ad applicare o modificare la soluzione.
Palec,

6

Con SQL Server 2012 e versioni successive è possibile utilizzare la FORMATfunzione

SELECT FORMAT(GETDATE(), 'dddd')

3

questa è una copia funzionante del mio codice verificalo, come recuperare il nome del giorno dalla data in 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

Se non vuoi dipendere @@DATEFIRSTo usare DATEPART(weekday, DateColumn), calcola tu stesso il giorno della settimana.

Per le settimane in base al lunedì (Europa) il più semplice è:

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

Per le settimane di domenica (America) utilizzare:

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

Questo restituisce il numero del giorno della settimana (da 1 a 7) dal 1 ° gennaio, rispettivamente, 7th, 1753.


1

È possibile utilizzare DATEPART(dw, GETDATE())ma tenere presente che il risultato si baserà sul @@DATEFIRSTvalore di impostazione del server SQL che è l' impostazione del primo giorno della settimana (in Europa valore predefinito 7 che è domenica).

Se si desidera modificare il primo giorno della settimana su un altro valore, è possibile utilizzare, SET DATEFIRSTma ciò può influire ovunque nella sessione di query che non si desidera.

Un modo alternativo è specificare esplicitamente il valore del primo giorno della settimana come parametro ed evitare a seconda @@DATEFIRSTdell'impostazione. È possibile utilizzare la seguente formula per ottenerlo quando necessario:

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

dove si @WeekStartDaytrova il primo giorno della settimana desiderato per il sistema (da 1 a 7, ovvero da lunedì a domenica).

L'ho avvolto nella seguente funzione in modo da poterlo riutilizzare facilmente:

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

Esempio di utilizzo: GetDayInWeek('2019-02-04 00:00:00', 1)

È equivalente al seguente (ma indipendente dall'impostazione DATEFIRST del server SQL):

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

0

Questa versione può essere 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
Questo è un codice ottuso, e non fornisce alcuna indicazione di ciò che sta facendo o cercando di raggiungere
brewmanz,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.