2012-07-12 122 views
2

我对SQL比较陌生,所以请原谅我,如果这是一个愚蠢的问题。现在我一直在尝试太久以使其发挥作用。将float(YYYY)转换为datetime

我在表A中有一列是一个名为ConstructionYear的浮动列。它有一个简单的4位数年份(即2010年,2005年,1972年等)。我需要使用这些年来填充表B的YearBuilt日期时间字段。我搜索并搜索并尝试了各种我在网上找到的convert()和cast()的不同组合,但它不起作用。

我想发生是这样的:

'2008' - > '2008-01-01 00:00:00.000'

'2005' - >“2005-01- 01 00:00:00.000'

'1986年' - > '1986年1月1日00:00:00.000'

而不是什么正在发生的事情(使用CAST(ConstructionYear AS DATETIME)):

'2008' - > '1905年7月2日00:00:00.000'

'2010' - > '1905年7月4日00:00:00.000'

'1984' - > '1905年6月8日00:00:00.000'

编辑:解决方法:cast(convert(varchar,@ConstructionYear) AS DATETIME)

所以我的问题有2个主要原因(比我是新来的SQL等)。

  1. 我不知道SQL Server用于datetime的1900年代。因为1905年的所有日期我都看到了,但我不知道它是在考虑我的2005年并将它算作1900年的日子。

  2. 1753年。为什么1753年我们可以使用最早的一年?在我发布我的问题之前,我可能在某个时候使用了正确的语法,但它没有运行,因为我的数据在1753年前已经有好几年了。我认为错误与我的代码有关。

+2

在这种情况下,Float似乎是一种存储整数的不好方法。根据字段的填充方式,你可能会稍微偏离需要被截断或舍入到(小)int或char(4) – automatic 2012-07-12 23:02:05

+0

之前舍入的值。同意,int列会更合适,以免得到一个1984.535在那里以某种方式 – Ghost 2012-07-12 23:08:37

+0

同意。我不幸地无法控制这些表格的结构,或者它们最初是如何由我们的客户填充的。 – tkrex 2012-07-12 23:25:44

回答

4

检查这个例子:

DECLARE @ConstructionYearas FLOAT 
SET @ConstructionYear = 2012 
SELECT FloatToDatetime = CAST(convert(varchar(4),@ConstructionYear) as datetime) 

它将欧tput的:

2012-01-01 00:00:00.000


基本上使用:

CAST(convert(varchar(4),@ConstructionYear) as datetime)

其中@ConstructionYear是您Float可变

希望它能帮助!

+0

非常真@AaronBertrand我不知道我错过了那个,thx! – Luis 2012-07-12 23:17:18

+1

我只是不喜欢在使用varchar的时候可以将浮点数,**号**,*作为数字*。改用日期数学!我是一名经验丰富的SQL Server开发人员/ dba,我甚至都不知道Convert(datetime,'2012')会工作......这不是我书中的有效日期。我不相信它。我相信我的直觉。我不能为这个答案投票。 – ErikE 2012-07-13 05:17:02

1

这应该工作,但有可能是一个更好的办法

CAST(CAST(ConstructionYear as nvarchar(4)) + '-01-01' as datetime) 

你的查询做的是您所提供的天数并将其添加到SQL服务器的时代,1900年1月1日,它给你看到的结果

1
DECLARE @y FLOAT; 
SELECT @y = 2012; 
SELECT DATEADD(YEAR, @y-1900, 0); 

你为什么想直接转换为数字值2012几年?实际上,在SQL Server中,数值将转换为自1900-01-01以来的天数。所以下面应该产生相同的结果:

SELECT CONVERT(DATETIME, 2012); 
SELECT DATEADD(DAY, 2012, '19000101'); 

正如其他人的建议,我强烈建议你正确地存储这些数据。虽然你可以使用一些像SMALLINT更安全一些,为什么不使用DATE?这具有内置验证功能,可以直接使用各种日期/时间功能而无需转换,并且不存在您可能遇到的任何类似FLOAT等近似数据类型的固有舍入问题。如果您要存储日期,请使用日期数据类型。

+0

我可以清楚地看到日子里发生了什么,因为将年份增加1会使日期时间增加1。我只是不知道1900年是基准年。 此外,我完全同意FLOAT不是存储此数据的适当方式。我希望我能改变这些桌子的结构,但不幸的是,他们是按原样交给我的。 – tkrex 2012-07-12 23:22:09

+1

这是此页面上的最佳答案。使用日期数学和日期函数。不要做愚蠢的字符串操作。人们(而不是亚伦),当它被格式化为人类的理解时,不要去思考它如何显示给你。开始思考计算机如何与代表价值的底层数据一起工作! – ErikE 2012-07-13 05:14:55