SQL Server隐式数据类型转换挑战

时间:2013-08-22 20:53:56

标签: sql-server-2012

在过去的20年里,我使用过许多数据库,并且只遇到了SQL Server这种“有趣”的隐式数据转换问题。

如果我创建一个包含一个小int列的表,并在其中插入值为1和2的两行,然后运行以下查询“从表中选择平均值(列)”我得到一个截断的结果而不是1.5我会从地球上几乎任何其他dB中获得自动升迁数据类型以存储整个结果而不是截断/舍入到列数据类型。现在我知道我可以针对每种可能的方案来解决这个问题,但不是一个好的动态解决方案,特别是对于使用数据分析产品的数据分析...... I.E:Cognos / Microstrategy等......

我在数据仓库中,并且其中包含数百万行的事实表...我希望存储小列并具有适当的聚合结果。我目前解决这个细微差别的方法是将最小的可量化列定义为数字(19,5)以解释所有情况,即使这些列多次只存储1或0,其中tinyint会很好但不会自然聚合好。

是否没有任何指令告诉SQL服务器做其他所有数据库(oracle / db2 / informix / access等等)的功能?哪个是推广到更大的类型并显示整个结果,让我做他想要的东西?

3 个答案:

答案 0 :(得分:1)

您可以在表格上创建视图,将smallinttinyint投射到float,并仅将这些视图发布给用户。这将保持较小的内存使用量。与其他必须使用不同数据类型进行聚合的数据库系统相比,转换应该没有开销。

答案 1 :(得分:1)

虽然它可能让您感到沮丧,但许多编程语言也会以这种方式表现出来,1 / 2会吐出0。参见:

With c++ integers, does 1 divided by 2 reliably equal 0, and 3/2 = 1, 5/2 = 2 etc.?

这是一个设计怪癖,如果改变它就会打破很多东西。您要问的是,您是否可以更改SQL Server行为的相对基本方式,从而可能会破坏服务器上运行的任何其他代码。

简单地说,不,你不能。

你错了所有其他数据库产品都是这样的,德比也做了同样的事情:

http://docs.oracle.com/javadb/10.6.2.1/ref/rrefsqlj32693.html

在Oracle文档中,他们特别警告您,无论原始类型如何,AVG都将返回浮点数。这是因为每种语言都必须做出选择,我会返回原始类型还是最准确的答案?为了阻止溢出,很多语言都选择了前者,让各地程序员不断受挫。

因此,在SQL Server中,为了获得一个浮动,请将一个浮动放入。

答案 2 :(得分:1)

据我所知,最快的方法是进行隐式演员:SELECT AVG(Field * 1.0)。你当然可以用同样的方式做一个明确的演员。据我所知,当你对它们求平均时,无法告诉SQL Server你想要将整数转换成浮点数,并且可以说这实际上是正确的行为。