
ROUND 函数
语法
sql
ROUND(expr[, digits])
功能说明
对数值进行四舍五入,返回指定精度的结果。
版本
v3.0.0.0 开始支持基本功能,v3.3.3.0 开始支持 digits 参数
返回结果类型
与输入字段的原始数据类型一致。
适用数据类型
expr:数值类型digits:数值类型(可选参数)
嵌套子查询支持
适用于内层查询和外层查询。
适用于
表和超级表。
使用说明
- 若
expr或digits为 NULL,返回 NULL。 - 若未指定
digits参数,默认值为 0,即四舍五入到整数。 - 若输入值是 INTEGER 类型,无论
digits值为多少,都只会返回 INTEGER 类型,不会保留小数。 digits大于零表示对小数位进行操作,四舍五入到digits位小数。若小数位数小于digits位,不进行四舍五入操作,直接返回。digits小于零表示丢弃小数位,并将数字四舍五入到小数点左侧digits位。若小数点左侧的位数小于digits位,返回 0。- 由于暂未支持 DECIMAL 类型,所以该函数会用 DOUBLE 和 FLOAT 来表示包含小数的结果,但是 DOUBLE 和 FLOAT 是有精度上限的,当位数太多时使用该函数可能没有意义。
- 只能与普通列、选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用。
示例所用表与数据(可直接复制执行)
sql
-- 建库与使用
CREATE DATABASE IF NOT EXISTS power;
USE power;
-- 智能电表表结构(带相位信息)
CREATE STABLE meters (
ts TIMESTAMP,
current FLOAT,
voltage INT,
phase FLOAT,
power DOUBLE
) TAGS (
groupid INT,
location VARCHAR(64)
);
-- 子表
CREATE TABLE d1001 USING meters TAGS (1, 'California.SanFrancisco');
CREATE TABLE d1002 USING meters TAGS (2, 'California.LosAngeles');
-- 写入数据
INSERT INTO d1001 VALUES
('2024-01-01 10:00:00.000', 10.387, 220, 30.456, 2286.134),
('2024-01-01 10:01:00.000', 12.625, 221, 45.789, 2790.125),
('2024-01-01 10:02:00.000', 8.549, 223, 60.234, 1906.427),
('2024-01-01 10:03:00.000', 11.234, 222, 120.567, 2493.948);
INSERT INTO d1002 VALUES
('2024-01-01 10:00:00.000', 9.085, 219, 0.123, 1989.615),
('2024-01-01 10:01:00.000', 14.076, 222, 90.678, 3124.872),
('2024-01-01 10:02:00.000', 7.268, 220, 180.345, 1598.960),
('2024-01-01 10:03:00.000', 10.512, 221, -30.890, 2323.152);
基础示例
示例 1: 基本用法(四舍五入到整数)
sql
-- 默认四舍五入到整数
taos> SELECT ROUND(123.456);
round(123.456) |
============================
124.000000000000000 |
taos> SELECT ROUND(123.456, 0);
round(123.456, 0) |
============================
124.000000000000000 |
-- 负数四舍五入
taos> SELECT ROUND(-78.923);
round(-78.923) |
============================
-79.000000000000000 |
示例 2: 指定小数位数
sql
-- 保留1位小数
taos> SELECT ROUND(123.456, 1);
round(123.456, 1) |
============================
123.500000000000000 |
-- 保留2位小数
taos> SELECT ROUND(123.456, 2);
round(123.456, 2) |
============================
123.460000000000000 |
-- 保留3位小数
taos> SELECT ROUND(8888.88888, 3);
round(8888.88888, 3) |
============================
8888.889000000000000 |
示例 3: 负数 digits(四舍五入到小数点左侧)
sql
-- 四舍五入到十位
taos> SELECT ROUND(8888.88, -1);
round(8888.88, -1) |
============================
8890.000000000000000 |
-- 四舍五入到百位
taos> SELECT ROUND(8888.88, -2);
round(8888.88, -2) |
============================
8900.000000000000000 |
-- 四舍五入到千位
taos> SELECT ROUND(8888.88, -3);
round(8888.88, -3) |
============================
9000.000000000000000 |
-- 四舍五入到万位
taos> SELECT ROUND(8888.88, -4);
round(8888.88, -4) |
============================
10000.000000000000000 |
示例 4: 超出整数位数范围
sql
-- 当整数部分位数不足时返回0
taos> SELECT ROUND(123.45, -4);
round(123.45, -4) |
============================
0.000000000000000 |
taos> SELECT ROUND(9.99, -3);
round(9.99, -3) |
============================
0.000000000000000 |
示例 5: NULL 值处理
sql
taos> SELECT ROUND(NULL);
round(null) |
========================
NULL |
taos> SELECT ROUND(123.456, NULL);
round(123.456, null) |
========================
NULL |
智能电表场景示例
示例 6: 电流数据精度调整
目的:将电流测量值四舍五入到指定精度,便于报表展示和数据分析。
sql
-- 四舍五入到整数,简化显示
SELECT ts,
current AS original_current,
ROUND(current) AS rounded_current
FROM d1001
ORDER BY ts;
ts | original_current | rounded_current |
====================================================================
2024-01-01 10:00:00.000 | 10.387000 | 10.000000000 |
2024-01-01 10:01:00.000 | 12.625000 | 13.000000000 |
2024-01-01 10:02:00.000 | 8.549000 | 9.000000000 |
2024-01-01 10:03:00.000 | 11.234000 | 11.000000000 |
应用价值:
- 简化数据展示
- 减少存储空间
- 便于快速判断电流等级
示例 7: 功率计费精度
目的:将功率值四舍五入到指定位数,符合电力计费标准。
sql
-- 保留2位小数用于计费
SELECT ts,
power AS original_power,
ROUND(power, 2) AS billing_power,
ROUND(power, 2) * 0.588 AS billing_amount
FROM d1001
ORDER BY ts;
应用价值:
- 符合电力计费标准(通常保留2位小数)
- 避免精度累积误差
- 简化账单显示
示例 8: 相位角度标准化
目的:将相位角度四舍五入到整数度,便于相位分析和故障诊断。
sql
-- 相位角四舍五入到整数
SELECT ts,
phase AS original_phase,
ROUND(phase) AS rounded_phase,
ROUND(phase, 1) AS phase_1decimal
FROM d1002
ORDER BY ts;
应用价值:
- 简化相位监控
- 便于相位不平衡检测
- 降低数据噪声影响
示例 9: 功率等级分类
目的:通过四舍五入到百位实现功率等级分类,便于负载管理。
sql
-- 按百瓦分类功率等级
SELECT ts,
power,
ROUND(power, -2) AS power_class,
CASE
WHEN ROUND(power, -2) < 2000 THEN '低负载'
WHEN ROUND(power, -2) < 3000 THEN '中负载'
ELSE '高负载'
END AS load_level
FROM meters
ORDER BY ts;
应用价值:
- 快速分类负载等级
- 简化负载监控
- 支持分级告警策略
示例 10: 统计分析中的精度控制
目的:在统计计算中控制结果精度,避免浮点误差累积。
sql
-- 计算平均功率并四舍五入
SELECT location,
AVG(power) AS avg_power_raw,
ROUND(AVG(power), 2) AS avg_power_rounded,
MAX(power) AS max_power,
ROUND(MAX(power), 2) AS max_power_rounded
FROM meters
WHERE ts >= '2024-01-01 10:00:00'
AND ts < '2024-01-01 10:04:00'
GROUP BY location;
应用价值:
- 控制统计结果的显示精度
- 避免过多无意义的小数位
- 提高报表可读性
示例 11: 电压波动范围分析
目的:分析电压波动,通过四舍五入识别电压等级。
sql
-- 将电压四舍五入到10V单位
SELECT ts,
voltage,
ROUND(voltage, -1) AS voltage_level_10v,
CASE
WHEN ROUND(voltage, -1) = 220 THEN '标准'
WHEN ROUND(voltage, -1) = 210 THEN '偏低'
WHEN ROUND(voltage, -1) = 230 THEN '偏高'
ELSE '异常'
END AS voltage_status
FROM d1001
ORDER BY ts;
应用价值:
- 快速识别电压等级
- 检测电压偏差
- 触发电压调节策略
示例 12: 能耗数据汇总
目的:按小时汇总能耗数据,并控制显示精度。
sql
-- 按小时统计能耗,四舍五入到整数千瓦时
SELECT _wstart AS hour,
ROUND(SUM(power) / 1000, 0) AS total_kwh
FROM d1001
WHERE ts >= '2024-01-01 10:00:00'
AND ts < '2024-01-01 11:00:00'
INTERVAL(1h);
应用价值:
- 简化能耗报表
- 便于与计费单位(千瓦时)对齐
- 提高数据可读性
生产场景应用与目的
场景 A: 计费系统数据标准化
目的:在电力计费系统中,需要将功率、电流等测量值四舍五入到标准精度,确保计费准确性和一致性。
示例:
sql
-- 生成标准化的计费数据
SELECT _wstart AS billing_period,
tbname AS meter_id,
ROUND(AVG(power), 2) AS avg_power_kw,
ROUND(SUM(power) * 0.001, 3) AS total_kwh,
ROUND(SUM(power) * 0.001 * 0.588, 2) AS billing_amount
FROM meters
WHERE ts >= '2024-01-01 00:00:00'
AND ts < '2024-01-02 00:00:00'
PARTITION BY tbname
INTERVAL(1d);
场景 B: 传感器数据去噪
目的:通过四舍五入消除传感器测量中的微小波动和噪声,提高数据质量。
示例:
sql
-- 去除电流测量中的噪声(保留1位小数)
SELECT ts,
ROUND(current, 1) AS filtered_current,
ROUND(phase, 0) AS filtered_phase
FROM meters
WHERE ts >= NOW - 1h
ORDER BY ts;
场景 C: 报表数据格式化
目的:为管理报表和数据可视化准备格式统一的数据,提高报表可读性。
示例:
sql
-- 生成格式化的日报表
SELECT location,
ROUND(AVG(voltage), 0) AS avg_voltage,
ROUND(AVG(current), 2) AS avg_current,
ROUND(AVG(power), 2) AS avg_power,
ROUND(MAX(power), 2) AS peak_power
FROM meters
WHERE ts >= CURRENT_DATE
AND ts < CURRENT_DATE + 1d
GROUP BY location;
场景 D: 告警阈值判断
目的:使用四舍五入后的值进行阈值比较,避免因浮点精度导致的误报。
示例:
sql
-- 检测功率超标(四舍五入到整数后比较)
SELECT ts,
tbname,
power,
ROUND(power, 0) AS power_rounded
FROM meters
WHERE ROUND(power, 0) > 3000
AND ts >= NOW - 1h
ORDER BY ts DESC;
场景 E: 数据压缩与存储优化
目的:通过降低数据精度减少存储空间,同时保持数据的有效性。
示例:
sql
-- 创建精度降低的历史数据归档
INSERT INTO meters_archive
SELECT ts,
ROUND(current, 1) AS current,
voltage,
ROUND(phase, 0) AS phase,
ROUND(power, 2) AS power
FROM meters
WHERE ts < NOW - 90d;
注意事项
-
精度限制:DOUBLE 类型最多保留约15-17位有效数字,超出部分可能丢失精度。
-
整数类型 :对整数类型使用 ROUND 函数不会改变其类型,即使指定了正的
digits值也不会产生小数。 -
边界情况:
- 当
digits为负数且绝对值大于整数部分位数时,结果为 0 - 当
digits为正数且大于实际小数位数时,不进行四舍五入,直接返回原值
- 当
-
浮点运算误差:由于浮点数的二进制表示特性,某些十进制小数无法精确表示,可能导致四舍五入结果与预期略有偏差。例如:
sqlSELECT ROUND(2.675, 2); -- 可能返回 2.67 而不是 2.68 -
NULL 传播:任一参数为 NULL 时结果为 NULL。
-
性能考虑:在处理大量数据时,建议在应用层进行格式化而非在查询中频繁使用 ROUND 函数。
-
与聚合函数配合:ROUND 可以嵌套在聚合函数内部或外部:
sqlSELECT ROUND(AVG(power), 2) FROM meters; -- 正确 SELECT AVG(ROUND(power, 2)) FROM meters; -- 正确
数学关系
- 四舍五入规则:当数字恰好在两个可能值的中间时(如 2.5),采用"向偶数舍入"(银行家舍入法)或"远离零舍入",具体取决于实现。
- 符号保留:负数的四舍五入保持符号,如 ROUND(-2.5) 可能返回 -2 或 -3。
- 与其他函数的关系 :
ROUND(x, 0) ≈ FLOOR(x + 0.5)(对于正数)ROUND(x, 0)与CEIL(x)和FLOOR(x)不同,后两者总是向上或向下取整
相关函数
- FLOOR:向下取整,总是返回不大于原值的最大整数
- CEIL:向上取整,总是返回不小于原值的最小整数
- TRUNCATE:截断函数,直接截取而不进行四舍五入
- ABS:绝对值函数,常与 ROUND 配合使用
- CAST:类型转换,可用于整数和浮点数之间的转换
函数意义与实际应用价值
数学意义
ROUND 函数基于标准的数学四舍五入规则,将数值调整到指定的精度级别。这是数值计算中最常用的近似方法之一,在保持数据有效性的同时简化表示。
实际应用价值
-
数据标准化
- 统一数据精度,便于数据交换和比对
- 符合行业标准和法规要求
- 简化数据存储和传输
-
误差控制
- 消除传感器测量噪声
- 避免浮点运算累积误差
- 提高数据质量和可靠性
-
用户友好性
- 简化数据显示,提高可读性
- 适配人类认知习惯
- 优化报表和可视化效果
-
计算优化
- 降低数据精度减少存储空间
- 简化后续计算
- 提高查询和分析性能
-
业务对齐
- 符合计费和结算标准
- 满足合规性要求
- 支持业务决策
关于 TDengine
TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台,其核心模块是高性能、集群开源、云原生、极简的时序数据库。
它能安全高效地将大量设备每天产生的高达 TB 甚至 PB 级的数据进行汇聚、存储、分析和分发,并提供 AI 智能体对数据进行预测与异常检测,提供实时的商业洞察。