合适的数据类型来保存百分比值?


Answers:


132

假设百分比上保留两位小数,则使用的数据类型取决于计划存储百分比的方式。如果要存储它们的分数等值(例如,将100.00%存储为1.0000),我将数据存储在decimal(5,4)具有CHECK约束的数据类型中,该约束确保值永远不会超过1.0000(假设是上限)并且永远不会低于0 (假设这是最低要求)。如果要存储其面值(例如,将100.00%存储为100.00),则应使用decimal(5,2)适当的CHECK约束条件。结合良好的列名,它可以使其他开发人员清楚地知道数据是什么以及如何将数据存储在列中。


12
难道不是decimal(5,2)2代表小数点分隔符后面的位数吗?
鲍里斯·卡伦斯

2
@BorisCallens-真不敢相信我这些年都错过了。是的,这是一个错字。decimal(5,2)应该使用检查约束捕获的内容。
2012年

4
我认为这最初是有的decimal(5,4),并decimal(5,2)在上面的评论之后更改为...我认为decimal(5,4)这是更好的定义-即您要存储0到1并保留2个小数位,而不是0到100。原因是百分比超出了100; 因此100%是100/100,即1。在大多数情况下100% * 100% = 100%,这样做是有意义的(例如,不是10000%; 1 * 1 = 1)。
JohnLBevan

4
@JohnLBevan-它花费在如何存储它们上。如果要按显示的值存储值(例如100.00),则需要decimal(5,2)。如果要将值存储为小数(例如1.0000),则需要decimal(5,4)。将更新帖子。
托马斯

谁能解释为什么您需要4位小数?不能使用2吗?如.91 === 91%或1.00 === 100%。我现在正在执行此操作,并且想知道4个地方的收益。像Pct十进制(10,2)这样的检查(Pct> =。01 AND Pct <= 1)。提前致谢。
MH

31
  • 坚持下去decimal
  • 如果要限制范围,请添加检查约束(例如,在0到100%之间;在某些情况下,可能有正当理由超过100%甚至可能达到负值)。
  • 将值1视为100%,将0.5视为50%,依此类推。这将使任何数学运算都能按预期运行(即,与将值100用作100%相对)。
  • 根据需要修改精度和小数columnName decimal(precision, scale)位数(这是括号中的两个值。精度表示该数字中可以保留的位数总数,小数位数表示小数点后的位数,因此decimal(3,2)可以表示一个数字)如#.##; decimal(5,3)将会是##.###
  • decimalnumeric在本质上是一样的。但是,decimal它符合ANSI,因此,除非另有说明,否则请始终使用它(例如,根据您公司的编码标准)。

示例方案

  • 对于您的情况(0.00%至100.00%),您需要decimal(5,4)
  • 对于最常见的情况(0%至100%),您会想要decimal(3,2)
  • 在上述两种情况下,检查约束都相同

例:

if object_id('Demo') is null
create table Demo
    (
        Id bigint not null identity(1,1) constraint pk_Demo primary key
        , Name nvarchar(256) not null constraint uk_Demo unique 
        , SomePercentValue decimal(3,2) constraint chk_Demo_SomePercentValue check (SomePercentValue between 0 and 1)
        , SomePrecisionPercentValue decimal(5,2) constraint chk_Demo_SomePrecisionPercentValue check (SomePrecisionPercentValue between 0 and 1)
    )

进一步阅读:


4

我同意Thomas的观点,并且至少在WPF应用程序中,我会选择DECIMAL(5,4)解决方案。

看一下MSDN数字格式字符串以了解原因:http : //msdn.microsoft.com/zh-cn/library/dwhawy9k#PFormatString

百分比(“ P”)格式说明符将数字乘以100,然后将其转换为代表百分比的字符串。

然后,您将可以在XAML代码中使用它:

DataFormatString="{}{0:P}"

2

如果您的精度为小数点后两位,则“ smallint”将在最小空间(2字节)中处理此精度。您存储百分比乘以100。

编辑:十进制类型可能是更好的匹配。然后,您无需手动缩放。每个值占用5个字节。


微软打破了那么多的它的链接.....
pcnate

0

使用numeric(n,n),其中n具有足够的分辨率以四舍五入为1.00。例如:

declare @discount numeric(9,9)
    , @quantity int
select @discount = 0.999999999
    , @quantity = 10000

select convert(money, @discount * @quantity)

3
这个问题在三年多以前得到了很高的评价。如果您正在寻找要回答的旧问题,请访问此处:stackoverflow.com/unanswered
valverij
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.