从数字获取 SQL Server 中的日期名称时出现问题
Posted
技术标签:
【中文标题】从数字获取 SQL Server 中的日期名称时出现问题【英文标题】:Problem when getting the day name in SQL Server from a number 【发布时间】:2021-01-15 12:45:25 【问题描述】:我正在尝试从 SQL 获取 dayname
,输入仅代表一周中的某一天的数字。
当我运行这段代码时
select
datename(dw, '20210115'),
datepart(dw, '20210115')
它返回Friday
,6
所以我以为6
这个数字的意思是Friday
然后我执行以下操作
select datename(dw, 6)
但不是返回Friday
,而是返回Sunday
那么,从 SQL Server 获取 dayname
并仅输入工作日数字的正确方法是什么?
【问题讨论】:
6 不是日期。datename
与 dates 一起使用,这意味着 6
被隐式转换为日期时间,就像调用了 cast(6 as datetime)
一样。具体来说,它被转换为1900-01-07
【参考方案1】:
DateName()
和 DatePart()
依赖于特定设置(例如 SET DATEFIRST
)
因此,虽然 6
的值现在对您来说可能代表“星期五”,但相同的代码可能会在不同的会话中为您或其他用户返回不同的值。
这就是为什么我不使用这些函数,而是创建一个包含元数据的日历表来通知我工作日。
我使用的代码如下所示:
...
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 0 THEN 1 ELSE 0 END As is_monday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 1 THEN 1 ELSE 0 END As is_tuesday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 2 THEN 1 ELSE 0 END As is_wednesday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 3 THEN 1 ELSE 0 END As is_thursday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 4 THEN 1 ELSE 0 END As is_friday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 5 THEN 1 ELSE 0 END As is_saturday
, CASE WHEN DateDiff(dd, '1900-01-01', the_date) % 7 = 6 THEN 1 ELSE 0 END As is_sunday
...
这将适用于所有 SQL Server 数据库,无论设置如何。
如果你希望它只返回日期名称,那么它可以写成:
CASE DateDiff(dd, '1900-01-01', the_date) % 7
WHEN 0 THEN 'Monday'
WHEN 1 THEN 'Tuesday'
WHEN 2 THEN 'Wednesday'
WHEN 3 THEN 'Thursday'
WHEN 4 THEN 'Friday'
WHEN 5 THEN 'Saturday'
WHEN 6 THEN 'Sunday'
END AS day_of_week
这种方法的工作原理
我们计算输入(在这些示例中为 the_date
)与已知的固定时间点之间的天数。
使用日期 1900-01-01
是因为它是“默认”(不是正确的词,但我现在想不出更好的词!)即 0
的值将被转换为。
1900-01-01
也恰好是一个星期一!
在那之后的每 7 天是另一个星期一,这就是模数 7 (% 7
) 位的作用!
【讨论】:
使用日历表似乎是最好的解决方案。谢谢以上是关于从数字获取 SQL Server 中的日期名称时出现问题的主要内容,如果未能解决你的问题,请参考以下文章
从查询 SQL Server 中的每个日期获取第一个和最后一个日期时间