类别:

数值函数 (舍入和截断)

ROUND

返回 input_expr 的四舍五入值。

另请参阅:

CEILFLOORTRUNCATE、TRUNC

语法

ROUND( <input_expr> [ , <scale_expr> [ , <rounding_mode> ] ] )
Copy
ROUND( EXPR => <input_expr> ,
       SCALE => <scale_expr>
       [ , ROUNDING_MODE => <rounding_mode>  ] )
Copy

实参

必填:

input_expr . OR . EXPR => input_expr

要执行操作的值或表达式。数据类型应为数值数据类型之一,例如 FLOAT 或 NUMBER。

如果指定 EXPR => 命名实参,则还必须指定 SCALE => 命名实参。

可选:

scale_expr . OR . SCALE => scale_expr

输出应包含在小数点后的位数。表达式的计算结果应为 -38 到 +38 之间的整数。

默认 scale_expr 值为零,这意味着该函数会移除小数点后的所有数字。

有关负数的信息,请参阅下面的使用说明。

如果指定 SCALE => 命名实参,则必须指定 EXPR => 为前面的命名实参。

rounding_mode . OR . ROUNDING_MODE => rounding_mode

要使用的舍入模式。您可以指定以下值中的一个:

  • 'HALF_AWAY_FROM_ZERO'。此模式将值 向远离零的方向舍入 (link removed)。

  • 'HALF_TO_EVEN'。此模式将值 舍入到最接近的偶数 (link removed)。

默认:'HALF_AWAY_FROM_ZERO'

如果指定 ROUNDING_MODE => 命名实参,则必须同时将 EXPR =>SCALE => 指定为前面的命名实参。

备注

如果为 rounding_mode 实参指定任一值,则 input_expr 的数据类型必须是 定点数的数据类型之一

此实参不支持 浮点数的数据类型 (例如 FLOAT)。

返回

返回类型基于输入类型:

  • 如果输入表达式是 FLOAT,则返回的类型是 FLOAT。

  • 如果输入表达式是 NUMBER,则返回的类型是 NUMBER。

    • 如果输入标度是常量:

      • 如果输入标度为正数,则返回类型的标度等于输入标度,精度足以涵盖任何可能的结果。

      • 如果输入标度为负数,则返回类型的标度为 0。

    • 如果输入标度不是常量,则返回类型的标度与输入表达式的标度相同。

如果标度为零,则该值实际上是一个 INTEGER。

例如:

  • ROUND(3.14::FLOAT, 1) 返回的数据类型为 FLOAT。

  • ROUND(3.14,1) 返回的 NUMBER 的标度为 1,精度至少为 3。

  • ROUND(-9.99,0) 返回的 NUMBER 的标度为 0,精度至少为 2。

  • ROUND(33.33,-1) 返回的 NUMBER 的标度为 0,精度至少为 3。

使用说明

  • 必须按名称或位置指定所有实参。不能按名称指定某些实参,也不能按位置指定其他实参。

    按名称指定实参时,不能在实参名称前后使用双引号。

  • 如果 scale_expr 为负数,则指定需要调整数字的小数点 之前 的位数。例如,如果标度为 -2,则结果是 100 的倍数。

  • 如果 scale_expr 大于输入表达式大小,则该函数不生效。

  • 如果 input_exprscale_expr 为 NULL,则结果为 NULL。

  • 默认情况下,小数点的半点向远离零的方向舍入。例如,-0.5 舍入为 -1.0。

    要更改舍入模式以将值 舍入到最接近的偶数 (link removed) (例如,将 -0.5 舍入为 0),请将 rounding_mode 实参传递入 'HALF_TO_EVEN'

    备注

    如果指定 rounding_mode 实参,则 input_expr 实参的数据类型必须是 定点数的数据类型之一

  • 浮点数是近似值。浮点数可能不会按预期舍入。

  • 如果舍入使数字超出数据类型的值范围,则该函数将返回错误。

示例

第一个示例展示了 ROUND 的简单用法,默认小数位数为 (0):

SELECT ROUND(135.135), ROUND(-975.975);
+----------------+-----------------+
| ROUND(135.135) | ROUND(-975.975) |
|----------------+-----------------|
|            135 |            -976 |
+----------------+-----------------+
Copy

下一个示例对标度参数使用一系列值:

SELECT n, scale, ROUND(n, scale)
  FROM test_ceiling
  ORDER BY n, scale;
+----------+-------+-----------------+
|        N | SCALE | ROUND(N, SCALE) |
|----------+-------+-----------------|
| -975.975 |    -1 |        -980     |
| -975.975 |     0 |        -976     |
| -975.975 |     2 |        -975.98  |
|  135.135 |    -2 |         100     |
|  135.135 |     0 |         135     |
|  135.135 |     1 |         135.1   |
|  135.135 |     3 |         135.135 |
|  135.135 |    50 |         135.135 |
|  135.135 |  NULL |            NULL |
+----------+-------+-----------------+
Copy

接下来的两个示例展示了使用默认舍入模式 ('HALF_AWAY_FROM_ZERO') 和 'HALF_TO_EVEN' 舍入模式之间的区别。这两个示例都调用了 ROUND 函数两次,第一次使用默认舍入行为,然后使用 'HALF_TO_EVEN'

第一个示例使用正输入值 2.5:

SELECT ROUND(2.5, 0), ROUND(2.5, 0, 'HALF_TO_EVEN');
Copy
+---------------+-------------------------------+
| ROUND(2.5, 0) | ROUND(2.5, 0, 'HALF_TO_EVEN') |
|---------------+-------------------------------|
|             3 |                             2 |
+---------------+-------------------------------+

第二个示例使用负输入值 -2.5:

SELECT ROUND(-2.5, 0), ROUND(2.5, 0, 'HALF_TO_EVEN');
Copy
+---------------+--------------------------------+
| ROUND(2.5, 0) | ROUND(-2.5, 0, 'HALF_TO_EVEN') |
|---------------+--------------------------------|
|            -3 |                             -2 |
+---------------+--------------------------------+

接下来的两个示例展示如何按名称(而不是按位置)指定函数的实参。

SELECT ROUND(
  EXPR => -2.5,
  SCALE => 0);
Copy
+---------------------------------+
| ROUND(EXPR => -2.5, SCALE => 0) |
|---------------------------------|
|                              -3 |
+---------------------------------+
SELECT ROUND(
  EXPR => -2.5,
  SCALE => 0,
  ROUNDING_MODE => 'HALF_TO_EVEN');
Copy
+------------------------------------------------------------------+
| ROUND(EXPR => -2.5, SCALE => 0, ROUNDING_MODE => 'HALF_TO_EVEN') |
|------------------------------------------------------------------|
|                                                               -2 |
+------------------------------------------------------------------+

下一个示例显示 FLOAT 值并不总是精确存储。如下图所示,在某些情况下,0.005 舍入为 0.01,而在其他情况下,舍入为 0。区别不在于舍入;区别实际上在于浮点数的基本表示形式;1.005 存储为一个略小于 1.005(约是 1.004999)的数字。但是,该 DECIMAL 值存储为精确数字,并在所有情况下都按预期舍入为 0.01。

创建并加载表:

CREATE OR REPLACE TEMP TABLE rnd1(f float, d DECIMAL(10, 3));
INSERT INTO rnd1 (f, d) VALUES
      ( -10.005,  -10.005),
      (  -1.005,   -1.005),
      (   1.005,    1.005),
      (  10.005,   10.005)
      ;
Copy

显示 FLOAT 舍入值和 DECIMAL 舍入值之间差异的示例:

select f, round(f, 2), 
       d, round(d, 2) 
    from rnd1 
    order by 1;
+---------+-------------+---------+-------------+
|       F | ROUND(F, 2) |       D | ROUND(D, 2) |
|---------+-------------+---------+-------------|
| -10.005 |      -10.01 | -10.005 |      -10.01 |
|  -1.005 |       -1    |  -1.005 |       -1.01 |
|   1.005 |        1    |   1.005 |        1.01 |
|  10.005 |       10.01 |  10.005 |       10.01 |
+---------+-------------+---------+-------------+
Copy
语言: 中文