Obter dia da semana no SQL Server 2005/2008

369

Se eu tenho uma data 01/01/2009, quero descobrir que dia era, por exemplo, segunda, terça, etc ...

Existe uma função interna para isso no SQL Server 2005/2008? Ou preciso usar uma tabela auxiliar?

um cavalo sem nome
fonte
11
Se você possui uma tabela que contém pesquisas para partes da data, geralmente fez algo errado. As funções de data do SQL Server são muitas e robustas; portanto, qualquer dado que você precise extrair de uma data pode ser prontamente feito em uma coluna de data e hora.
22730 Benjamin Autin
6
mesas auxiliares são muito úteis para cálculos de data, não é incomum ter um calendário de mesa auxiliar ...
2
"Útil para cálculos de datas" é altamente duvidoso. A maioria dos cálculos de datas pode ser manipulada sem qualquer tipo de tabela auxiliar e terá um desempenho melhor também. Em alguns casos, uma tabela simples de números fará o trabalho - não há necessidade de uma tabela com datas reais. A única razão pela qual vi que uma tabela de calendário real é necessária é quando as regras para quais dias são dias úteis e quais não são são muito complicadas. O que eu tenho visto com muita frequência são as pessoas que usam tabelas de datas porque não sabem como fazê-lo de outra maneira. Então eles precisam preencher a tabela de datas de vez em quando. Boba.
ErikE
5
Vou comer minhas palavras se você puder me mostrar um uso para tabelas de calendário que 1) não é para regras complexas de feriado / dia de trabalho, 2) não pode ser feito facilmente com funções internas e 3) somente se não # 2, uma tabela do Numbers funciona tão bem e não requer que a tabela seja preenchida com datas específicas.
11119 ErikE
2
Os data warehouses fazem uso extensivo de tabelas de calendário. Os meses, trimestres, anos, etc. pré-calculados fornecem aos usuários finais campos com os quais eles podem filtrar / agregar.
David Rushton

Respostas:

694

Use DATENAMEou DATEPART:

SELECT DATENAME(dw,GETDATE()) -- Friday
SELECT DATEPART(dw,GETDATE()) -- 6
SQLMenace
fonte
thx, eu tentei o nome do dado, mas usei d, me retornou um número inteiro. dw funciona conforme o esperado
39
É por isso que eu prefiro usar select datename (dia da semana, getdate ()). Não preciso lembrar que o dw retorna o dia da semana ... quando eu posso usar o "dia da semana".
George Mastros
9
qualquer um que olhe para isso - observe que o início da semana padrão é domingo . Olhe para resposta da @ Sung para saber como mudar isso com segurança
JonnyRaa
2
@niico é porque os índices SQL de 1, enquanto C gostam do índice de idiomas de 0. #
user824276
95

Mesmo que a resposta do SQLMenace tenha sido aceita, há uma SETopção importante que você deve conhecer

SET DATEFIRST

DATENAME retornará o nome correto da data, mas não o mesmo valor DATEPART, se o primeiro dia da semana tiver sido alterado, conforme ilustrado abaixo.

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
dance2die
fonte
33
Então, para obter um valor constante da data, você precisa ( @@datefirst - 1 + datepart(weekday, thedate) ) % 7. Domingo será sempre zero.
Endy Tjahjono 23/02
11
kindof horrível este material é estática para que você tem que seguir o original consulta, altere o valor, consulta correr, redefinir padrão original
JonnyRaa
2
Parte engraçada disto é que o .NET DayOfWeekenumeração tem DayOfWeek.Sundaycom um valor de ... 0. Portanto, não importa o que DateFirstestiver definido, um valor retornado por SQL não tratadoWEEKDAY nunca será compatível com o equivalente do .NET. Sim, 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
Sutirth
fonte
26
Você deve saber que existe uma função integrada para obter o mesmo. select datename(dw,getdate())
Soham Dasgupta
10
@SohamDasgupta, essa função integrada não retorna o mesmo resultado para a versão não inglesa do MS SQL.
Scapegrace 23/11
12

Para obter um valor determinístico para o dia da semana em uma determinada data, você pode usar uma combinação de DATEPART () e @@ datefirst . Caso contrário, você depende das configurações do servidor.

Confira o site a seguir para uma solução melhor: MS SQL: dia da semana

O dia da semana estará no intervalo de 0 a 6, onde 0 é domingo, 1 é segunda-feira etc. Então você pode usar uma declaração de caso simples para retornar o nome correto do dia da semana.

lazerwire.com
fonte
5
Coloque a resposta na resposta para que as pessoas não precisem clicar em um link para acessá-lo.
Martin Smith
11

EUROPA:

declare @d datetime;
set @d=getdate();
set @dow=((datepart(dw,@d) + @@DATEFIRST-2) % 7+1);
npg
fonte
2
Inclua explicações sobre o que seu código faz e como ele responde à pergunta. Se você receber um trecho de código como resposta, talvez não saiba o que fazer com ele. A resposta deve fornecer ao OP e aos futuros visitantes orientações sobre como depurar e corrigir o problema. Assinalar, qual é a idéia por trás do seu código, ajuda muito a entender o problema e a aplicar ou modificar sua solução.
Palec 02/02
6

Com o SQL Server 2012 em diante, você pode usar a FORMATfunção

SELECT FORMAT(GETDATE(), 'dddd')
Chris Stillwell
fonte
3

esta é uma cópia de trabalho do meu código, verifique, como recuperar o nome do dia da data no 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
Tapan kumar
fonte
1

Se você não quiser depender @@DATEFIRSTou usar DATEPART(weekday, DateColumn), apenas calcule o dia da semana.

Nas semanas de segunda-feira (Europa), o mais simples é:

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

Para semanas baseadas no domingo (América), use:

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

Isso retorna o número do dia da semana (1 a 7) desde 1º de janeiro, respectivamente, 7 de janeiro de 1753.

Michel de Ruiter
fonte
1

Você pode usar, DATEPART(dw, GETDATE())mas esteja ciente de que o resultado dependerá do @@DATEFIRSTvalor de configuração do servidor SQL, que é o primeiro dia da semana (na Europa, o valor padrão 7 é domingo).

Se você deseja alterar o primeiro dia da semana para outro valor, pode usar, SET DATEFIRSTmas isso pode afetar todos os lugares da sua sessão de consulta que você não deseja.

Uma maneira alternativa é especificar explicitamente o valor do primeiro dia da semana como parâmetro e evitar dependendo da @@DATEFIRSTconfiguração. Você pode usar a seguinte fórmula para conseguir isso quando necessário:

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

onde @WeekStartDayé o primeiro dia da semana que você deseja para o seu sistema (de 1 a 7, o que significa de segunda a domingo).

Coloquei-o na função abaixo para que possamos reutilizá-lo 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

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

É equivalente ao seguinte (mas independente da configuração DATEFIRST do SQL Server):

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

Você pode encontrar esta versão ú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 
Reto
fonte
11
Este é o código obtuso, e não dá nenhuma indicação de que ele está fazendo ou tentando alcançar
brewmanz