SQL将Int转换为Date或Char

1 人关注

我的数据库有6位数的日期格式,数据类型为int('734503'=01/01/2012)。 我已经能够成功地将这些数据转换为字符。

SELECT CONVERT(char(12),dateadd(dd,(date_paid - 639906),'1/1/1753'),101)  
FROM   vouchers       
WHERE date_paid = '734503'

这给我的输出是01/01/2012。 但如果我在这样的查询中搜索转换后的日期。

SELECT CONVERT(char(12),dateadd(dd,(date_paid - 639906),'1/1/1753'),101) 
FROM vouchers    
WHERE date_paid >= '09/01/2012' AND date_paid <= '09/30/2012'

为什么没有进行转换? 即使我在date_paid字段的WHERE语句中使用CONVERT,它也不应该在那里工作吗?

我想我的问题是如何用转换后的字符日期进行搜索,而不必使用6位数的日期?

7 个评论
为什么不使用一个日期类型的字段?
你可能必须在WHERE部分进行转换,而不是在SELECT部分。
@Bart...这不是我的数据库。 如果是我,我会用日期类型来构建它......让事情更简单。 它是一个ERP系统的骨干。
@Bart再次......如果你看到,我试图在WHERE语句中进行转换......它仍然不工作。
@PuroRock - 在你问题中的 WHERE 子句中,没有做任何转换的代码。唯一的转换代码是在 SELECT 子句中。
@Bart......在选择语句中的转换,然后在WHERE子句中的date_paid >= '09/01/2012',例如,不工作......它没有拉出结果。
@PuroRock - 在 SELECT 子句中的转换与 WHERE 子句的行为绝对 没有关系 。 如果你想让 WHERE 子句使用转换代码,你需要把转换代码写在那里 也是如此 .
sql
sql-server-2008
PuroRock
PuroRock
发布于 2012-10-19
2 个回答
MatBailie
MatBailie
发布于 2012-10-19
已采纳
0 人赞同

你的问题是,你正在比较一个INT列和STRING值,并期望它能像比较日期一样解决。

WHERE date_paid >= '09/01/2012'
AND date_paid <= '09/30/2012'
-- date_paid is an INT (according to your question)
-- '09/01/2012' is a STRING

由于数据类型的不同,这里有一个 隐含的CAST()在那里。 实际上,你在做...

WHERE CAST(date_paid AS VARCHAR(10)) >= '09/01/2012'
AND CAST(date_paid AS VARCHAR(10)) <= '09/30/2012'
-- NOTE:  All of these values are now strings
--        They may LOOK like dates, but they're just strings

你真正需要做的是 明确地说将字符串处理成整数。

WHERE date_paid >= DATEDIFF(DAY, '01/01/1753', '09/01/2012') + 639906
AND date_paid <= DATEDIFF(DAY, '01/01/1753', '09/30/2012') + 639906

这也涉及到隐式转换。 DATEDIFF()只接受DATETIME数据类型,所以字符串首先被隐式地转换为DATETIME。

另一个选择是将date_paid字段 CAST()转换成DateTime,然后在此基础上进行WHERE计算。 这里的缺点是...
- CAST()必须在每一条记录上完成,然后应用WHERE子句
- 这就避免了索引的使用,大大降低了性能。

上面的答案在常量值上做了所有的处理,所以搜索的字段可以在它的原始状态下被处理;从而允许使用索引。

或者,更好的做法是,在将INT值存储到数据库之前,将其转换为DATETIME值。
谢谢你,但对于隐式CAST()或CONVERT(),我总是得到0个结果...这是不真实的。 我明白我是在比较INT和STRING,但正如我所写的,即使我在WHERE子句中使用了我的CONVERT(),它仍然没有工作(同样,0结果)。 我可以使用显式操作(它几乎是有效的,它拉出了10月份的日期),但需要通过一个变量来传递它。
请看我的第三个代码块。 它向你展示了如何将 '09/01/2012' 转换成一个INT。 这意味着你可以传入一个DATETIME或VARCHAR(10)作为参数,用代码把它处理成一个INT,然后把这个INT与你的数据进行比较。
就像现在,如果你只是做 CAST(date_paid AS DATETIME) ,你会得到像 CAST(734503 AS DATETIME) 这样的东西,它给出了一个非常遥远的未来日期。 或者,如果你做 CAST(734503 AS VARCHAR(10)) [隐式 显式],你就会得到 '634503' 这样的字符串。
好的,将尝试。 我也试过转换/转换INT并转储到一个临时表,然后选择我的date_paid范围,但它随后选择了正确的月份,但拉出了表中的每一年。
Charles Bretana
Charles Bretana
发布于 2012-10-19
0 人赞同

首先,如果你可以的话,改变你的数据库模式。 date_paid列的数据类型应该是 datetime date ,而不是'int'或'char'。

...但是如果你坚持使用这个模式,那么你的 date_paid 值似乎是整数,其中693596的值代表 1 jan 1900 日。 (这个日期是SQL Server零值的映射位置。)所以你需要做的就是转移,或者将你的搜索值偏移到这个数量。

假设你想搜索的日期是今天,2012年10月19日

 Declare @SearchDate DateTime = '20 Oct 2012'

然后把你的查询谓词写成。