【问题标题】:Convert column of type Float to Date in sql-server在 sql-server 中将 Float 类型的列转换为 Date
【发布时间】:2020-05-22 10:03:03
【问题描述】:

我的日期存储在一个浮点列中,我试图将其更改为时间戳,但没有成功, 现在我想从那个字段计算年龄,我已经尝试了使用CONVERTCAST 函数的各种组合,但它似乎不起作用。

DoB
-434419200000
606960000000
1332806400000
1395878400000
-87350400000
890956800000

我试过了:

 SELECT DATEADD(ss, dob, '19700101')
   from tbl

   //Result
   Error overflow .. arithmetique for type int, value= -434419200000.000000

    SELECT DATEADD(ss, CONVERT(bigint, dob, 101), '19700101')
    from tbl

    //Result
     Error while conversion from expression to type int.

更新

注意这里的数据是从日期“1970/1/1 00:00:00”开始的毫秒数

谢谢。

【问题讨论】:

  • -434419200000 代表什么“日期”..?您在它上面所做的所有代码都从float-434419200000 转换为varchar(未指定长度)。它不做任何年龄计算。
  • 以时间戳表示出生日期,但该列是float类型,在我获取数据作为日期后,年龄计算是进一步的步骤。
  • 您必须弄清楚谁或什么在存储这些值以及它们的含义。这种时间戳方法不是 SQL Server 原生的。您不能使用任何内置类型从日期中获取负数。例如,-434419200000 可能是从 1970-01-01 开始的 Unix 日期/时间值(以毫秒为单位),因此它代表的 DOB 为 1956-03-27,但这纯粹是推测,没有看到实际处理值。如果它 Unix 时间戳,请参阅here
  • -434419200000 对于 int 来说太小了,您需要使用 bigint
  • 问题不在于float,而在于DATEADD 不支持除INT 之外的任何东西并且没有DATEADD_BIGSELECT DATEADD(SECOND, CONVERT(BIGINT, -434419200000) / 1000, '19700101').

标签: sql-server tsql date timestamp


【解决方案1】:

正确的数据类型应该是 bigint 而不是浮点数。事实上,我宁愿在date 列中导入时间戳。

话虽如此,将数字除以1000以避免溢出错误:

select dateadd(second, -434419200000e0 / 1000, '1970-01-01')
-- 1956-03-27 00:00:00.000

【讨论】:

  • 非常感谢,尽管列的数据类型,现在它可以工作了,请您开发这个以获取从现在开始的年龄,谢谢
【解决方案2】:

正如我在 cmets 中提到的,这是问题 converting Epoch timestamp to sql server(human readable format)How to calculate age (in years) based on Date of Birth and getDate() 的组合副本。

样本数据:

CREATE TABLE dbo.YourTable (DoB float);
INSERT INTO dbo.YourTable (DoB)
VALUES (-434419200000),
       (606960000000),
       (1332806400000),
       (1395878400000),
       (-87350400000),
       (890956800000);

然后使用我们得到的第一个链接:

SELECT DATEADD(SECOND, DoB / 1000,'19700101') --As yours is milliseconds, not seconds.
FROM dbo.YourTable;

那么我们可以使用第二个链接的答案:

SELECT YT.DoB,
       V.DateOfBirth,
       CONVERT(int,DATEDIFF(yy, V.DateOfBirth, GETDATE()) + 
       CASE WHEN GETDATE() >= DATEFROMPARTS(DATEPART(yyyy, GETDATE()), DATEPART(m, V.DateOfBirth), DATEPART(d, V.DateOfBirth)) THEN (1.0 * DATEDIFF(DAY, DATEFROMPARTS(DATEPART(yyyy, GETDATE()), DATEPART(m, V.DateOfBirth), DATEPART(d, V.DateOfBirth)), GETDATE()) / DATEDIFF(DAY, DATEFROMPARTS(DATEPART(yyyy, GETDATE()), 1, 1), DATEFROMPARTS(DATEPART(yyyy, GETDATE()) + 1, 1, 1)))
            ELSE -1 * (-1.0 * DATEDIFF(DAY, DATEFROMPARTS(DATEPART(yyyy, GETDATE()), DATEPART(m, V.DateOfBirth), DATEPART(d, V.DateOfBirth)), GETDATE()) / DATEDIFF(DAY, DATEFROMPARTS(DATEPART(yyyy, GETDATE()), 1, 1), DATEFROMPARTS(DATEPART(yyyy, GETDATE()) + 1, 1, 1)))
       END) AS Age
FROM dbo.YourTable YT
     CROSS APPLY (VALUES (DATEADD(SECOND, YT.DoB / 1000, '19700101'))) V (DateOfBirth);

如果这个答案有帮助,我建议也支持我在上面链接的答案,因为这是上述答案的组合。

【讨论】:

  • 好的,谢谢,我错过了@SalmanA 提到的除以 1000。
猜你喜欢
  • 1970-01-01
  • 2015-11-05
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
相关资源
最近更新 更多