【问题标题】:SQL Server 2008 R2 - convert all datetime parts (as ints) into a datetime columnSQL Server 2008 R2 - 将所有日期时间部分(作为整数)转换为日期时间列
【发布时间】:2016-10-24 11:29:42
【问题描述】:

我有一个表,其中将日期时间片段(年、月、日、小时、分钟、秒、毫秒)存储为整数。我想将它们连接成一个 datetime 列。

我尝试了各种方法,但都没有奏效 - 似乎没有简单的方法可以将这些项目放在一起?

【问题讨论】:

  • 如果您可以升级到 SQL Server 2012 或更高版本,您可以使用DATEFROMPARTS
  • @marc_s 实际上,datetimefromparts...
  • @ZoharPeled:绝对正确 - 热量正在进入我的大脑,似乎 :-) 谢谢

标签: tsql datetime sql-server-2008-r2 integer concatenation


【解决方案1】:

您可以将每个部分转换为 varchar 并以 ISO 日期时间字符串的格式将它们连接在一起。然后使用Convert 将字符串转换为DateTime

这是一个例子。您需要将每个硬编码整数替换为表中列的名称。

SELECT CONVERT(DATETIME, CAST(2016 AS VARCHAR(4)) -- year
    + '-' + CAST('0' + CAST(8 AS VARCHAR(2)) AS VARCHAR(2)) -- month
    + '-' + RIGHT('0' + CAST(13 AS VARCHAR(2)), 2) -- day of month
    + 'T' + RIGHT('0' + CAST(16 AS VARCHAR(2)), 2) -- hours (I assume its military time (24 hours))
    + ':' + RIGHT('0' + CAST(32 AS VARCHAR(2)), 2) -- minutes
    + ':' + RIGHT('0' + CAST(07 AS VARCHAR(2)), 2) -- seconds
    + '.' + RIGHT('000' + CAST(64 AS VARCHAR(3)), 3)) AS MyDate -- milliseconds
FROM yourTable

或使用列名(假设)

SELECT CONVERT(DATETIME, CAST(yt.Year AS VARCHAR(4)) -- year
    + '-' + CAST('0' + CAST(yt.Month AS VARCHAR(2)) AS VARCHAR(2)) -- month
    + '-' + RIGHT('0' + CAST(yt.Day AS VARCHAR(2)), 2) -- day of month
    + 'T' + RIGHT('0' + CAST(yt.Hours AS VARCHAR(2)), 2) -- hours (I assume its military time (24 hours))
    + ':' + RIGHT('0' + CAST(yt.Minutes AS VARCHAR(2)), 2) -- minutes
    + ':' + RIGHT('0' + CAST(yt.Seconds AS VARCHAR(2)), 2) -- seconds
    + '.' + RIGHT('000' + CAST(yt.Milliseconds AS VARCHAR(3)), 3)) AS MyDate -- milliseconds
FROM yourTable yt

还有一个注意事项。 Microsoft 建议您使用 DateTime2 而不是 DateTime 来保留从 Sql Server 2008(您在问题中标记)开始的日期时间值。

【讨论】:

  • 您需要使用T 作为分隔符来创建ISO 8601 日期时间字符串。否则 SQL Server 将尝试将字符串解析为特定于语言环境的字符串
  • @PanagiotisKanavos - 谢谢,我更正了我的答案。
  • 这很好 - 谢谢!我不得不稍微修改我的毫秒值,因为我的长度是 6 位数,而 datetime 数据类型需要三位数。谢谢!!
【解决方案2】:

在sql server 2012之前,可以使用一系列嵌套的DATEADD()函数来模仿DATETIMEFROMPARTS()函数

创建和填充示例数据(在您的下一个问题中,请保存我们这一步)

DECLARE @T as table
(
    cYear int,
    cMonth int,
    cDay int,
    cHour int,
    cMinute int,
    cSecond int,
    cMillisecond int
)

INSERT INTO @T VALUES(2016, 6, 22, 16, 34, 25, 3)

查询:

SELECT *,
        DATEADD(MILLISECOND, cMillisecond, 
            DATEADD(SECOND, cSecond, 
                DATEADD(MINUTE, cMinute, 
                    DATEADD(HOUR, cHour, 
                        DATEADD(DAY, cDay -1, 
                            DATEADD(MONTH, cMonth - 1, 
                                DATEADD(YEAR, cYear - 2000, '2000-01-01')
                            )
                        )
                    )
                )
            )
        ) As TheDate
FROM @T 

结果:

cYear   cMonth   cDay   cHour   cMinute   cSecond   cMillisecond TheDate
-----   ------   ----   -----   -------  -------   ------------- -----------------------
2016    6        22     16      34        25        3            2016-06-22 16:34:25.003

请注意,我使用的基准日期是 2000 年 1 月 1 日,因此您需要从年中减去 2000,从月中减去 1,从天中减去 1。

【讨论】:

  • 谢谢!我选择了第二个答案,但我也可以看到你的价值。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-29
  • 2012-08-14
  • 1970-01-01
  • 2016-06-29
  • 2013-10-31
  • 2013-01-13
相关资源
最近更新 更多