为了回答这里的另一个问题,我创建了以下数据结构和行:
create table [resource] (Name varchar(16),date datetime, project varchar(16),hours int)
INSERT INTO resource
values ('Andy Sandy', '2013-03-02', 'Enhancements',40)
INSERT INTO resource
values('Fred Jones', '2013-10-02', 'Enhancements',40)
我执行了以下查询:
select
case when sum(hours) > 0 Then
CAST(SUM(hours) as DECIMAL(5,2))/40
else 0 end as [hours],
[DATE]
from resource group by date
结果如下:
Hours Date
1.000000 2013-03-02 00:00:00.000
1.750000 2013-10-02 00:00:00.000
当我将小时数转换为小数时,我指定了5的精度和2的标度。我不明白为什么数字是这样的。如果我没有指定精度和比例,那么结果是相同的。这是为什么?
答案 0 :(得分:3)
你正在做numeric(5,2)
/ 40。
来自Precision, Scale, and Length
+-----------+------------------------------------+---------------------+
| Operation | Result precision | Result scale * |
+-----------+------------------------------------+---------------------+
| e1 / e2 | p1 - s1 + s2 + max(6, s1 + p2 + 1) | max(6, s1 + p2 + 1) |
+-----------+------------------------------------+---------------------+
将40视为numeric(2,0)
,因为这是保留精度和比例的最小十进制表示。
所以
p1=5
s1=2,
p2=2
s2=0
然后将其插入BOL中的公式
Precision: 5 - 2 + 0 + max(6, 2 + 2 + 1) = 9
Scale: max(6, 2 + 2 + 1) = 6
结果是numeric(9,6)
。
你也可以从
看到这一点;WITH cte(thing) AS
(
SELECT CAST(1 as DECIMAL(5,2))/40
)
SELECT thing,
sql_variant_property(thing,'basetype') AS basetype,
sql_variant_property(thing,'precision') AS precision,
sql_variant_property(thing,'scale') AS scale,
sql_variant_property(thing,'maxlength') AS maxlength
FROM cte
返回
+----------+----------+-----------+-------+-----------+
| thing | basetype | precision | scale | maxlength |
+----------+----------+-----------+-------+-----------+
| 0.025000 | decimal | 9 | 6 | 5 |
+----------+----------+-----------+-------+-----------+
(注意:decimal
和numeric
是同义词)
答案 1 :(得分:2)
sp_describe_first_result_set N'
select
case when sum(hours) > 0 Then
CAST(SUM(hours) as DECIMAL(5,2))/40
else 0 end as [hours],
[DATE]
from resource group by date'
您会看到您返回的小时列正在被转换为十进制(9,6)。
如果您将原始演员表改为例如DECIMAL(10,6),则将其重新编号为(14,10)。所以你认为它只增加了4级的十进制精度。不太好!
将分频器从40.0更改为400.0 - 现在它转换为(15,11) - 它还会根据分频器的精度增加额外的精度。
将其更改为40.0000(3个额外的零) - 现在是(20,15)。因此,有一个功能可以根据原始值和除数来确定精度。
小数点右侧的每个额外精度等级都会为原始强制转换增加(2,1)。 左侧的每个精度等级都会将(1,1)加到原始投射上。
要将小时列返回为十进制(5,2),您只需要执行
select
case when sum(hours) > 0 Then
CAST(SUM(hours) /40.0 as decimal(5,2))
else 0 end as [hours],
[DATE]
from resource group by date