Obtenga el día de la semana en SQL Server 2005/2008


369

Si tengo una fecha 01/01/2009, quiero saber qué día fue, por ejemplo, lunes, martes, etc.

¿Existe una función integrada para esto en SQL Server 2005/2008? ¿O necesito usar una mesa auxiliar?


1
Si tiene una tabla que contiene búsquedas de porciones de fechas, generalmente ha hecho algo mal. Las funciones de fecha de SQL Server son muchas y robustas, por lo que cualquier dato que necesite extraer de una fecha se puede hacer fácilmente en una columna de fecha y hora.
Benjamin Autin

66
mesas auxiliares son muy útiles para los cálculos de fechas, no es raro tener una mesa auxiliar calendario ...

2
"Útil para los cálculos de fechas" es muy dudoso. La mayoría de los cálculos de fechas se pueden manejar sin ningún tipo de tabla auxiliar y también funcionarán mejor. En algunos casos, una tabla simple de Números hará el trabajo, sin necesidad de una tabla con fechas reales. La única razón por la que he visto que se necesita una tabla de calendario real es cuando las reglas para qué días son días de trabajo y cuáles no son muy complicadas. Lo que he visto con demasiada frecuencia es que las personas usan tablas de fechas porque no saben cómo hacerlo de otra manera. Luego tienen que llenar la tabla de fechas de vez en cuando. Tonto.
ErikE

55
Me comeré mis palabras si puede mostrarme un uso para las tablas de calendario que 1) no es para reglas complejas de vacaciones / días laborables, 2) no se puede hacer fácilmente con funciones integradas y 3) solo si no # 2, entonces una tabla de Números funciona igual de bien y no requiere llenar la tabla con fechas específicas.
ErikE

2
Los almacenes de datos hacen un uso extensivo de las tablas de calendario. Los meses, trimestres, años, etc. precalculados proporcionan a los usuarios finales campos con los que pueden filtrar / agregar.
David Rushton

Respuestas:


694

Usar DATENAMEo DATEPART:

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

Gracias, intenté datename pero usé d, me devolvió un número entero. dw funciona como se esperaba

39
Es por eso que prefiero usar select datename (día de la semana, getdate ()). No tengo que recordar que dw devuelve el día de la semana ... cuando puedo usar "día de la semana" en su lugar.
George Mastros

99
cualquiera que esté mirando esto: tenga en cuenta que el inicio de semana predeterminado es el domingo . Mire la respuesta de @ Sung sobre cómo cambiar eso de manera segura
JonnyRaa

2
@niico se debe a que SQL indexa desde 1 mientras que a C le gustan los idiomas desde 0.
user824276

95

Aunque la respuesta de SQLMenace ha sido aceptada, hay una SETopción importante que debe tener en cuenta

SET DATEFIRST

DATENAME devolverá el nombre correcto de la fecha pero no el mismo valor DATEPART si el primer día de la semana se ha cambiado como se ilustra a continuación.

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
Entonces, para obtener un valor constante de datepart, lo hace ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. El domingo siempre será cero.
Endy Tjahjono

1
tipo de horrible, esto es estático, por lo que debe seguir la consulta original, cambiar el valor, ejecutar la consulta, restablecer el patrón original
JonnyRaa

2
Lo gracioso de esto es que de .NET DayOfWeekenumeración tiene DayOfWeek.Sundayun valor de ... 0. Por lo tanto, no importa lo establecido DateFirst, un valor devuelto por SQL no tratadoWEEKDAY nunca será compatible con la contraparte .NET. Yay, 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
Debe saber que hay una función integrada para lograr lo mismo. select datename(dw,getdate())
Soham Dasgupta

10
@SohamDasgupta esta función integrada no devuelve el mismo resultado para la versión no inglesa de MS SQL.
Mr Scapegrace

12

Para obtener un valor determinista para el día de la semana para una fecha determinada, puede usar una combinación de DATEPART () y @@ datefirst . De lo contrario, dependerá de la configuración del servidor.

Consulte el siguiente sitio para obtener una mejor solución: MS SQL: Día de la semana

El día de la semana estará entonces en el rango de 0 a 6, donde 0 es domingo, 1 es lunes, etc. Luego puede usar una declaración de caso simple para devolver el nombre correcto del día de la semana.


55
Ponga la respuesta en la respuesta para que las personas no tengan que hacer clic en un enlace para acceder.
Martin Smith

11

EUROPA:

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

2
Incluya una explicación de lo que hace su código y cómo responde la pregunta. Si obtiene un fragmento de código como respuesta, es posible que no sepa qué hacer con él. La respuesta debería dar al OP y a los futuros visitantes una guía sobre cómo depurar y solucionar su problema. Señalar cuál es la idea detrás de su código, es de gran ayuda para comprender el problema y aplicar o modificar su solución.
Palec

6

Con SQL Server 2012 y versiones posteriores, puede usar la FORMATfunción

SELECT FORMAT(GETDATE(), 'dddd')

3

esta es una copia de trabajo de mi código, verifíquelo, cómo recuperar el nombre del día desde la fecha 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 no quiere depender @@DATEFIRSTo usar DATEPART(weekday, DateColumn), calcule el día de la semana usted mismo.

Para las semanas basadas en lunes (Europa) lo más simple es:

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

Para las semanas de domingo (América) use:

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

Esto devuelve el número del día de la semana (1 a 7) desde el 1 de enero, respectivamente, el 7 de 1753.


1

Puede usar, DATEPART(dw, GETDATE())pero tenga en cuenta que el resultado dependerá del @@DATEFIRSTvalor de configuración del servidor SQL, que es la configuración del primer día de la semana (en Europa, el valor predeterminado 7 es el domingo).

Si desea cambiar el primer día de la semana a otro valor, puede usarlo, SET DATEFIRSTpero esto puede afectar a todas las partes de su sesión de consulta que no desee.

Una forma alternativa es especificar explícitamente el valor del primer día de la semana como parámetro y evitar depender de la @@DATEFIRSTconfiguración. Puede usar la siguiente fórmula para lograrlo cuando lo necesite:

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

donde @WeekStartDayes el primer día de la semana que desea para su sistema (del 1 al 7, lo que significa de lunes a domingo).

Lo he incluido en la siguiente función para que podamos reutilizarlo fácilmente:

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

Ejemplo de uso: GetDayInWeek('2019-02-04 00:00:00', 1)

Es equivalente a lo siguiente (pero independiente de la configuración DATEFIRST del servidor SQL):

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

0

Puede encontrar esta versión útil.

-- 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
Este es el código obtuso, y no da ninguna indicación de lo que está haciendo o tratando de lograr
brewmanz
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.