在 SQL Server 2005/2008 中获取星期几

Posted

技术标签:

【中文标题】在 SQL Server 2005/2008 中获取星期几【英文标题】:Get day of week in SQL Server 2005/2008 【发布时间】:2010-11-09 19:21:38 【问题描述】:

如果我有一个日期 01/01/2009,我想知道它是哪一天,例如周一、周二等...

SQL Server 2005/2008 中是否为此提供了内置函数?还是我需要使用辅助表?

【问题讨论】:

如果您有一个包含日期部分查找的表,那么您通常做错了什么。 SQL Server 的日期函数数量众多且功能强大,因此您需要从日期中提取的任何数据都可以在日期时间列上轻松完成。 辅助表对于日期计算非常有用,有日历辅助表并不稀奇... “对日期计算有用”是非常可疑的。大多数日期计算都可以在没有任何类型的辅助表的情况下处理,并且性能也会更好。在某些情况下,一个普通的 Numbers 表就可以完成这项工作——不需要包含实际日期的表。我看到需要一个实际日历表的唯一原因是,哪些日子是工作日,哪些日子不是很复杂的规则。我经常看到人们使用日期表,因为他们不知道如何以其他方式进行操作。然后他们必须经常填充日期表。傻。 如果你能告诉我一个日历表的用途,我会吃掉我的话 1) 不适用于复杂的假日/工作日规则,2) 不能通过内置函数轻松完成, 和 3) 仅当不是 #2 时,Numbers 表也可以正常工作,并且不需要使用特定日期填充表。 数据仓库广泛使用日历表。预先计算的月份、季度、年份等为最终用户提供了他们可以过滤/聚合的字段。 【参考方案1】:

使用DATENAMEDATEPART

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

【讨论】:

thx,我尝试过 datename 但使用了 d,给了我一个整数。 dw 按预期工作 这就是为什么我更喜欢使用 select datename(weekday,getdate())。我不必记住 dw 返回 weekday.... 当我可以使用 "weekday" 时。 任何人都看过这个 - 请注意,默认的一周开始时间是星期日。看看@Sung 的回答,了解如何安全地改变它 @niico 这是因为 SQL 从 1 开始索引,而 C 语言从 0 开始索引。 今天找到这个答案,让我毛骨悚然的是,您的答案中的示例结果与我的匹配,然后发现 2009 年 7 月的日子与今天(2020 年 7 月)的日子相同,无论如何感谢简单的答案。【参考方案2】:

尽管SQLMenace's answer 已被接受,但您应该注意一个重要的SET 选项

SET DATEFIRST

DATENAME 将返回正确的日期name,但如果一周的第一天已更改,则返回的 DATEPART 值将不一样,如下图所示。

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

【讨论】:

所以要获得恒定的 datepart 值,您可以使用( @@datefirst - 1 + datepart(weekday, thedate) ) % 7。星期日永远是零。 有点可怕,这个东西是静态的,所以你必须按照查询原始,更改值,运行查询,重置原始模式 有趣的是,.NET 的 DayOfWeek 枚举具有 DayOfWeek.Sunday 的值 ... 0。因此,无论 DateFirst 设置为什么,未处理 SQL 返回的 WEEKDAY 值永远不会与 .NET 对应项兼容。是的,微软。【参考方案3】:
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

【讨论】:

您应该知道有一个内置函数可以实现相同的功能。 select datename(dw,getdate()) @SohamDasgupta 这个内置函数不会为非英语版本的 MS SQL 返回相同的结果。【参考方案4】:

欧洲:

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

【讨论】:

请说明您的代码的作用以及它如何回答问题。如果您得到一个代码 sn-p 作为答案,您可能不知道如何处理它。答案应该为 OP 和未来的访问者提供有关如何调试和解决问题的指导。指出您的代码背后的想法是什么,对理解问题以及应用或修改您的解决方案有很大帮助。 这个答案应该改进,但它仍然是唯一一个无需致电SET DATEFIRST就可以为我提供我想要的值的答案。【参考方案5】:

要获得给定日期的星期几的确定值,您可以使用DATEPART() 和@@datefirst 的组合。否则你依赖于服务器上的设置。

查看以下网站以获得更好的解决方案: MS SQL: Day of Week

星期几将在 0 到 6 的范围内,其中 0 是星期日,1 是星期一,等等。然后您可以使用简单的 case 语句返回正确的工作日名称。

【讨论】:

请将答案放入答案中,这样人们就不必单击链接即可获得它。 这对我没有任何帮助,它只是一个点击诱饵【参考方案6】:

在 SQL Server 2012 及更高版本中,您可以使用 FORMAT 函数

SELECT FORMAT(GETDATE(), 'dddd')

【讨论】:

【参考方案7】:

这是我的代码的工作副本检查它,如何从 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

【讨论】:

【参考方案8】:

如果您不想依赖@@DATEFIRST 或使用DATEPART(weekday, DateColumn),只需自己计算星期几。

对于基于星期一的周(欧洲),最简单的是:

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

对于基于星期日的周(美国)使用:

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

这将返回自 1753 年 1 月 1 日和 7 日以来的工作日编号(1 到 7)。

【讨论】:

【参考方案9】:

您可以使用DATEPART(dw, GETDATE()),但请注意,结果将取决于 SQL 服务器设置 @@DATEFIRST 值,这是一周中的第一天设置(在欧洲,默认值为 7,即星期日)。

如果您想将一周的第一天更改为另一个值,您可以使用SET DATEFIRST,但这可能会影响您查询会话中您不想要的任何地方。

另一种方法是显式指定一周中的第一天值作为参数,并避免依赖于@@DATEFIRST 设置。您可以在需要时使用以下公式来实现:

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

@WeekStartDay 是您希望系统在一周中的第一天(从 1 到 7 表示从星期一到星期日)。

我已经将它包装到下面的函数中,以便我们可以轻松地重用它:

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

示例用法: GetDayInWeek('2019-02-04 00:00:00', 1)

等同于以下(但独立于 SQL server DATEFIRST 设置):

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

【讨论】:

【参考方案10】:

除以上所有答案外,dw 代表工作日

SELECT DATENAME(WEEKDAY,GETDATE()) AS WeekDay

SELECT DATENAME(W,GETDATE()) AS WeekDay

【讨论】:

【参考方案11】:

您可能会发现此版本对于在一行中返回缩短的工作日名称很有用。

-- 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 

【讨论】:

这是迟钝的代码,并没有说明它正在做什么或试图实现什么

以上是关于在 SQL Server 2005/2008 中获取星期几的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL Server 2000/2005/2008 中使用 FLOAT 转换小数位数

Sql Server 2005/2008数据库被标记为“可疑”/“质疑”的问题

Sql Server 2005/2008数据库被标记为“可疑”的解决办法

WiX 引导程序的示例应用程序(检查 .NET Framework 和 SQL Server 2005/2008)

SQL Server 2005/2008/2012中应用分布式分区视图

SET ANSI_NULLS ON SET QUOTED_IDENTIFIER ON 什么意思 sql server 2005 2008