在过去的20年里,我使用过许多数据库,并且只遇到了SQL Server这种“有趣”的隐式数据转换问题。
如果我创建一个包含一个小int列的表,并在其中插入值为1和2的两行,然后运行以下查询“从表中选择平均值(列)”我得到一个截断的结果而不是1.5我会从地球上几乎任何其他dB中获得自动升迁数据类型以存储整个结果而不是截断/舍入到列数据类型。现在我知道我可以针对每种可能的方案来解决这个问题,但不是一个好的动态解决方案,特别是对于使用数据分析产品的数据分析...... I.E:Cognos / Microstrategy等......
我在数据仓库中,并且其中包含数百万行的事实表...我希望存储小列并具有适当的聚合结果。我目前解决这个细微差别的方法是将最小的可量化列定义为数字(19,5)以解释所有情况,即使这些列多次只存储1或0,其中tinyint会很好但不会自然聚合好。
是否没有任何指令告诉SQL服务器做其他所有数据库(oracle / db2 / informix / access等等)的功能?哪个是推广到更大的类型并显示整个结果,让我做他想要的东西?
答案 0 :(得分:1)
您可以在表格上创建视图,将smallint
或tinyint
投射到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你想要将整数转换成浮点数,并且可以说这实际上是正确的行为。