select DATENAME(month,29*5)
任何人都可以告诉我上述查询背后的逻辑 当月号作为整数提供时,它如何始终返回正确的月份名称。
答案 0 :(得分:2)
Datetime
值存储在8个字节中
前4个字节代表日期,后4个字节代表时间。
在日期部分,日期存储为自1900-01-01
以来的天数。
在时间部分,它是自午夜以来的时钟滴答数
每秒有300个时钟滴答,因此滴答为3.33333毫秒
这也是为什么日期时间仅精确到.003
秒的原因。
此查询有望帮助解释:
SELECT CAST(0 As datetime) As Date_0,
29*5 As NumberOfDays,
CAST(29*5 as datetime) As TheDate,
DATENAME(month,29*5) As TheMonthName
结果:
Date_0 NumberOfDays TheDate TheMonthName
----------------------- ------------ ----------------------- ------------
1900-01-01 00:00:00.000 145 1900-05-26 00:00:00.000 May
至于你问题的最后一部分,29(28也会起作用)是这里的神奇数字 - 30太大了(5月会回来4和5)而27太小了 - (9月会是返回9和10) 基本上我只是数学 - 正确地得到这个数字,这样每次你用1到12之间的任何数字加倍它都会给你一些天数,总计一天属于正确的月份。
您可以使用此脚本自行测试:
DECLARE @MagicNumber int = 28
;With cte as
(
select 1 as num
union all
select num + 1
from cte
where num < 12
)
SELECT num, DATENAME(month, @MagicNumber * num ) As TheMonthName
from cte
只需更改@MagicNumber
的值,然后查看您获得的结果。
答案 1 :(得分:0)
我想我能解释一下。
任何日期数据类型的默认年 - 月 - 日是1900-01-01。如果我们考虑上面的选择查询,它会将29 * 5天添加到默认日期并提供MONTHNAME。
Select DATENAME(month,29*5)
现在了解DATENAME
DateName - 返回表示指定日期的指定日期部分的字符串。它有不同的-2参数,并根据datepart给出不同的-2结果。
参数1 - 是返回日期的一部分。
参数2 - 是一个任何日期(是一个可以解析为a的表达式 time,date,smalldatetime,datetime,datetime2或datetimeoffset 值。)
这里我们将month
作为第一个参数。这意味着它返回monthname
。
29*5
的计算会给出145
答案,如果我们只是将其转换为日期,则将其视为日期并计算为1900-01-01 + 145
并给出日期 1900-05-26 00:00:00.000 强>
意味着如果我们得到这个月将给5 - MAY作为答案。
执行此查询并检查上述逻辑的答案。
Select DATENAME(month,29*5), (29*5) , DATENAME(month, '12:10:30.123'), DATENAME(month, getdate())
select cast (145 as datetime)
DECLARE @t datetime = '12:10:30.123';
SELECT DATENAME(month, 29*5), 145/30.00;
进一步检查。 MSDN Link
Convert Month Number to Month Name Function in SQL(查看@ user275683答案)
答案 2 :(得分:0)
如果您只想显示与月份编号对应的月份,那么您应该使用这样的。
declare @intMonth as int
set @intMonth = 5
Select DateName( month , DateAdd( month , @intMonth , -1 ))