任何人都可以告诉我背后的逻辑选择DATENAME(月,29 * 5)

时间:2016-05-19 04:23:48

标签: sql-server sql-server-2008

select DATENAME(month,29*5)

任何人都可以告诉我上述查询背后的逻辑 当月号作为整数提供时,它如何始终返回正确的月份名称。

3 个答案:

答案 0 :(得分:2)

Sql server中的

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