

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 数字类型
<a name="Numeric_types"></a>

数字数据类型包括整数、小数和浮点数。

**Topics**
+ [整数类型](Numeric_types-integer-types.md)
+ [DECIMAL 或 NUMERIC 类型](Numeric_types-decimal-or-numeric-type.md)
+ [浮点类型](Numeric_types-floating-point-types.md)
+ [数值计算](Numeric_computations.md)

# 整数类型
<a name="Numeric_types-integer-types"></a>

使用以下数据类型来存储不同范围的整数。您无法存储每种类型所允许范围之外的值。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/sql-reference/Numeric_types-integer-types.html)

# DECIMAL 或 NUMERIC 类型
<a name="Numeric_types-decimal-or-numeric-type"></a>

使用 DECIMAL 或 NUMERIC 数据类型存储具有*用户定义的精度* 的值。DECIMAL 和 NUMERIC 关键字是可互换的。在本文档中，*小数* 是此数据类型的首选术语。术语*数字* 一般用于指整数、小数和浮点数据类型。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/sql-reference/Numeric_types-decimal-or-numeric-type.html)

通过指定*precision*和在表中定义 DECIMAL 列*scale*：

```
decimal(precision, scale)
```

 *precision*   
整个值中有效位的总数：小数点两边的位数。例如，数字 `48.2891` 的精度为 6，小数位数为 4。如果未指定，默认精度为 18。最大精度为 38。  
 如果输入值中的小数点左侧的位数超出了列的精度减去其小数位数的差值，则此值无法复制到列中（或无法插入或更新）。此规则适用于列定义范围之外的任何值。例如，`numeric(5,2)` 列所允许的值范围为 `-999.99` 到 `999.99`。

 *scale*   
值的小数部分中小数点右侧的小数位数。整数的小数位数为零。在列规范中，小数位数值必须小于或等于精度值。如果未指定，默认小数位数为 0。最大小数位数为 37。  
如果加载到表中的输入值的小数位数大于列的小数位数，则该值将四舍五入到指定小数位数。例如，SALES 表中的 PRICEPAID 列为 DECIMAL(8,2) 列。如果将 DECIMAL(8,4) 值插入到 PRICEPAID 列中，则该值将四舍五入到小数位数 2。  

```
insert into sales
values (0, 8, 1, 1, 2000, 14, 5, 4323.8951, 11.00, null);

select pricepaid, salesid from sales where salesid=0;

pricepaid | salesid
-----------+---------
4323.90 |       0
(1 row)
```
 但是，对于显示强制转换表中选定的值而得出的结果，不会进行四舍五入。

**注意**  
您可插入到 DECIMAL(19,0) 列中的最大正值为 `9223372036854775807` (263 -1)。最大负值为 `-9223372036854775807`。例如，尝试插入值 `9999999999999999999`（19 个 9）将导致溢出错误。无论小数点的位置如何， AWS Clean Rooms 可表示为 DECIMAL 数的最大字符串为 `9223372036854775807`。例如，您可加载到 DECIMAL(19,18) 列中的最大值为 `9.223372036854775807`。  
制定这些规则的原因如下：  
有效精度为 19 位或更少的 DECIMAL 值在内部存储为 8 字节整数。
有效精度为 20-38 的 DECIMAL 值在内部存储为 16 字节整数。

## 有关使用 128 位 DECIMAL 或 NUMERIC 列的说明
<a name="Numeric_types-notes-about-using-128-bit-decimal-or-numeric-columns"></a>

请勿为 DECIMAL 列随意分配最高精度，除非您确定您的应用程序需要此精度。128 位值使用的磁盘空间是 64 位值的两倍，并且可能会降低查询执行速度。

# 浮点类型
<a name="Numeric_types-floating-point-types"></a>

使用 REAL 和 DOUBLE PRECISION 数据类型可存储具有*可变精度* 的数值。这些类型是*不精确的* 类型，意味着一些值是作为估计值存储的，因此存储和返回某个特定值可能导致细微的差异。如果您需要精确的存储和计算（如货币金额），请使用 DECIMAL 数据类型。

根据 IEEE 浮点运算标准 754，REAL 表示单精度浮点数格式。它的精度约为 6 位，范围在 1E-37 到 1E\$137 之间。您也可以将此数据类型指定为 FLOAT4。

根据 IEEE 二进制浮点运算标准 754，DOUBLE PRECISION 表示双精度浮点数格式。它的精度约为 15 位，范围在 1E-307 到 1E\$1308 之间。您也可以将此数据类型指定为 FLOAT 或 FLOAT8。

# 数值计算
<a name="Numeric_computations"></a>

在中 AWS Clean Rooms，*计算*是指二进制数学运算：加法、减法、乘法和除法。此部分介绍这些运算的预期返回类型，以及在涉及 DECIMAL 数据类型时应用于确定精度和小数位数的特定公式。

当在查询处理期间计算数值时，您可能会遇到无法计算和查询返回数字溢出错误的情况。您还可能会遇到计算值的小数位数发生变化或出乎意料的情况。对于一些运算，您可使用显式强制转换（类型提升）或 AWS Clean Rooms 配置参数来解决这些问题。

有关类似使用 SQL 函数的计算的结果的信息，请参阅[AWS Clean Rooms 火花 SQL 函数](sql-functions-topic-spark.md)。

## 计算的返回类型
<a name="Numeric_computations-return-types"></a>

给定中支持的数值数据类型集 AWS Clean Rooms，下表显示了加法、减法、乘法和除法运算的预期返回类型。表左侧第一列表示计算中的第一个操作数，顶部行表示第二个操作数。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/sql-reference/Numeric_computations.html)

## 计算的 DECIMAL 结果的精度和小数位数
<a name="Numeric_computations-precision-and-scale-of-computed-decimal-results"></a>

下表汇总了在数学运算返回 DECIMAL 结果时用于计算生成的精度和小数位数的规则。在此表中，`p1`和`s1`表示计算中第一个操作数的精度和小数位数。 `p2`并`s2`表示第二个操作数的精度和小数位数。（不管这些计算如何，最大的结果精度为 38，最大的结果小数位数为 38）。

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/zh_cn/clean-rooms/latest/sql-reference/Numeric_computations.html)

例如，SALES 表中的 PRICEPAID 和 COMMISSION 列均为 DECIMAL(8,2) 列。如果您用 PRICEPAID 除以 COMMISSION（或者反过来），采用的公式如下所示：

```
Precision = 8-2 + 2 + max(4,2+8-2+1)
= 6 + 2 + 9 = 17

Scale = max(4,2+8-2+1) = 9

Result = DECIMAL(17,9)
```

以下计算是使用集合运算符（如 UNION、INTERSECT 和 EXCEPT）或 COALESCE 和 DECODE 等函数计算对 DECIMAL 值执行的运算的最终精度和小数位数的一般规则：

```
Scale = max(s1,s2)
Precision = min(max(p1-s1,p2-s2)+scale,19)
```

例如，将 DEC1 具有一个十进制 (7,2) 列的 DEC2 表与具有一个十进制 (15,3) 列的表连接以创建表。 DEC3 的架构 DEC3 显示该列变为数字 (15,3) 列。

```
select * from dec1 union select * from dec2;
```

在上例中，采用的公式如下所示：

```
Precision = min(max(7-2,15-3) + max(2,3), 19)
= 12 + 3 = 15

Scale = max(2,3) = 3

Result = DECIMAL(15,3)
```

## 有关除法运算的说明
<a name="Numeric_computations-notes-on-division-operations"></a>

对于除法运算， divide-by-zero条件会返回错误。

在计算精度和小数位数之后，将应用小数位数最多为 100 的限制。如果计算所得的结果小数位数大于 100，则除法运算结果的范围如下所示：
+ 精度 = ` precision - (scale - max_scale)` 
+ 小数位数 = ` max_scale ` 

如果计算所得的精度大于最大精度 (38)，则精度将减少为 38，小数位数的结果将介于以下范围：`max(38 + scale - precision), min(4, 100))`

## 溢出条件
<a name="Numeric_computations-overflow-conditions"></a>

将检查所有数值计算是否存在溢出情况。精度为 19 或 19 以下的 DECIMAL 数据存储为 64 位整数。精度大于 19 的 DECIMAL 数据存储为 128 位整数。所有 DECIMAL 值的最大精度为 38，最大小数位数为 37。当值超出这些限制时将出现溢出错误，中间结果集和最终结果集都存在这种情况：
+ 当特定数据值不符合强制转换函数指定的请求精度或比例时，显式转换会导致运行时溢出错误。例如，您无法强制转换 SALES 表中 PRICEPAID 列（DECIMAL(8,2) 列）的所有值并返回 DECIMAL(7,3) 结果：

  ```
  select pricepaid::decimal(7,3) from sales;
  ERROR:  Numeric data overflow (result precision)
  ```

  此错误出现的原因是 PRICEPAID 列中的*一些* 较大的值无法强制转换。
+ 乘法运算的乘积结果中的小数位数为所有操作数的小数位数之和。例如，如果两个操作数的小数位数都为 4，则结果的小数位数为 8，小数点左侧仅剩下 10 位。因此，在具有有效小数位数的两个大数相乘时，遇到溢出的情况相对容易一些。

## INTEGER 和 DECIMAL 类型的数值计算
<a name="Numeric_computations-numeric-calculations-with-integer-and-decimal-types"></a>

如果计算中的一个操作数具有 INTEGER 数据类型且另一个操作数为 DECIMAL，则 INTEGER 操作数将隐式强制转换为 DECIMAL：
+ SMALLINT 或 SHORT 被转换为十进制 (5,0) 
+ INTEGER 将强制转换为 DECIMAL(10,0) 
+ BIGINT 或 LONG 被转换为十进制 (19,0) 

例如，如果将 SALES.COMMISSION（DECIMAL(8,2) 列）和 SALES.QTYSOLD（SMALLINT 列）相乘，则此计算将强制转换为：

```
DECIMAL(8,2) * DECIMAL(5,0)
```