TDengine 数学函数 TRUNCATE 用户手册

TRUNCATE 函数

语法

sql 复制代码
TRUNCATE(expr, digits)

功能说明

获得指定字段按照指定位数截断的值。

版本

v3.3.3.0

返回结果类型

expr 字段的原始数据类型一致。

适用数据类型

  • expr:数值类型。
  • digits:数值类型。

嵌套子查询支持

适用于内层查询和外层查询。

适用于

表和超级表。

使用说明

  • exprdigits 为 NULL,返回 NULL。
  • 截断是按保留位数直接进行截断,没有四舍五入。
  • digits 大于零表示对小数位进行操作,截取到 digits 位小数,若小数位数小于 digits 位,不进行截断操作,直接返回。
  • digits 等于零表示丢掉小数位。
  • digits 小于零表示丢掉小数位,并将小数点左侧 digits 位置为 0。若小数点左侧的位数小于 digits 位,返回 0。
  • 由于暂未支持 DECIMAL 类型,所以该函数会用 DOUBLE 和 FLOAT 来表示包含小数的结果,但是 DOUBLE 和 FLOAT 是有精度上限的,当位数太多时使用该函数可能没有意义。
  • 只能与普通列、TAG 列、选择(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.3456, 220, 30.1234, 2266.789),
  ('2024-01-01 10:01:00.000', 12.6789, 221, 45.5678, 2790.654),
  ('2024-01-01 10:02:00.000',  8.5432, 223, 60.9876, 1895.543),
  ('2024-01-01 10:03:00.000', 11.2345, 222, 90.4321, 2486.432);

INSERT INTO d1002 VALUES
  ('2024-01-01 10:00:00.000',  9.0123, 219, 0.0, 1971.012),
  ('2024-01-01 10:01:00.000', 14.0987, 222, 120.3456, 3108.098),
  ('2024-01-01 10:02:00.000',  7.2654, 220, 180.6789, 1584.265),
  ('2024-01-01 10:03:00.000', 10.5876, 221, -30.9876, 2320.587);

基础示例

示例 1: 保留小数位截断

sql 复制代码
-- 保留1位小数
taos> SELECT TRUNCATE(8888.88, 1);
 truncate(8888.88, 1)    |
============================
    8888.800000000000000 |

-- 保留2位小数
taos> SELECT TRUNCATE(123.456, 2);
 truncate(123.456, 2)    |
============================
     123.450000000000000 |

-- 保留0位小数(去掉小数部分)
taos> SELECT TRUNCATE(8888.88, 0);
 truncate(8888.88, 0)    |
============================
    8888.000000000000000 |

示例 2: 整数位截断

sql 复制代码
-- 截断到十位(个位变为0)
taos> SELECT TRUNCATE(8888.88, -1);
 truncate(8888.88, -1)   |
============================
    8880.000000000000000 |

-- 截断到百位(十位和个位变为0)
taos> SELECT TRUNCATE(123.456, -2);
 truncate(123.456, -2)   |
============================
     100.000000000000000 |

-- 截断到千位
taos> SELECT TRUNCATE(8888.88, -3);
 truncate(8888.88, -3)   |
============================
    8000.000000000000000 |

示例 3: NULL 值处理

sql 复制代码
taos> SELECT TRUNCATE(NULL, 2);
  truncate(null, 2)  |
========================
 NULL                  |

taos> SELECT TRUNCATE(123.456, NULL);
 truncate(123.456, null) |
===========================
 NULL                     |

示例 4: 列数据截断

sql 复制代码
-- 截断电流值到1位小数
SELECT ts,
       current,
       TRUNCATE(current, 1) AS current_truncated
FROM d1001
ORDER BY ts;
复制代码
           ts            |  current  | current_truncated |
====================================================================
 2024-01-01 10:00:00.000 | 10.345600 |    10.300000000000000 |
 2024-01-01 10:01:00.000 | 12.678900 |    12.600000000000000 |
 2024-01-01 10:02:00.000 |  8.543200 |     8.500000000000000 |
 2024-01-01 10:03:00.000 | 11.234500 |    11.200000000000000 |

智能电表场景示例

示例 5: 电量计费精度控制

目的:将功率值截断到2位小数用于计费,避免四舍五入可能带来的累积误差。

sql 复制代码
-- 截断功率值到2位小数用于精确计费
SELECT ts,
       power,
       TRUNCATE(power, 2) AS power_for_billing,
       TRUNCATE(power, 2) * 0.588 AS billing_amount
FROM d1001
ORDER BY ts;

应用价值

  • 确保计费精度一致性
  • 避免四舍五入累积误差
  • 符合电费计量规范

示例 6: 电压等级分类

目的:将电压值截断到十位,用于电压等级统计和分析。

sql 复制代码
-- 按十位截断电压值进行等级分类
SELECT ts,
       voltage,
       TRUNCATE(voltage, -1) AS voltage_level,
       CASE
         WHEN TRUNCATE(voltage, -1) = 220 THEN '标准电压'
         WHEN TRUNCATE(voltage, -1) = 210 THEN '偏低电压'
         WHEN TRUNCATE(voltage, -1) = 230 THEN '偏高电压'
         ELSE '异常电压'
       END AS voltage_category
FROM meters
ORDER BY ts;

应用价值

  • 简化电压等级统计
  • 识别电压波动模式
  • 优化电压调节策略

示例 7: 功率统计精度处理

目的:按不同精度截断功率数据,用于不同级别的统计报表。

sql 复制代码
-- 生成不同精度的功率统计(使用聚合函数后再截断)
SELECT location,
       TRUNCATE(AVG(power), 0) AS avg_power_integer,
       TRUNCATE(AVG(power), 1) AS avg_power_1decimal,
       TRUNCATE(AVG(power), 2) AS avg_power_2decimal
FROM meters
WHERE ts >= '2024-01-01 10:00:00'
  AND ts < '2024-01-01 10:04:00'
GROUP BY location;

应用价值

  • 满足不同报表精度要求
  • 减少数据存储空间
  • 提高数据可读性

示例 8: 电流阈值判断

目的:截断电流值后进行阈值判断,避免微小波动导致的误判。

sql 复制代码
-- 截断电流到1位小数后判断是否超限
SELECT ts,
       current,
       TRUNCATE(current, 1) AS current_truncated,
       CASE
         WHEN TRUNCATE(current, 1) > 12.0 THEN '超载'
         WHEN TRUNCATE(current, 1) > 10.0 THEN '高负载'
         WHEN TRUNCATE(current, 1) < 8.0 THEN '低负载'
         ELSE '正常'
       END AS load_status
FROM meters
ORDER BY ts;

应用价值

  • 避免告警抖动
  • 稳定负载监控
  • 优化告警策略

示例 9: 相位角标准化

目的:将相位角截断到整数,便于后续分析。

sql 复制代码
-- 截断相位角到整数
SELECT ts,
       phase,
       TRUNCATE(phase, 0) AS phase_integer,
       TRUNCATE(phase, 1) AS phase_1decimal
FROM meters
WHERE ts >= '2024-01-01 10:00:00'
  AND ts < '2024-01-01 10:04:00'
ORDER BY ts;

应用价值

  • 简化相位分析
  • 识别相位分布特征
  • 评估三相平衡度

示例 10: 能耗分段统计

目的:按功率区间(百位)进行能耗分段统计。

sql 复制代码
-- 先截断功率再统计各区间数量
SELECT tbname,
       power,
       TRUNCATE(power, -2) AS power_range_100
FROM meters
WHERE ts >= '2024-01-01 10:00:00'
  AND ts < '2024-01-01 10:04:00'
ORDER BY power_range_100;

应用价值

  • 负载分布分析
  • 能耗模式识别
  • 容量规划依据

示例 11: 计量数据规范化

目的:统一截断各项计量数据到标准精度,便于数据对比和分析。

sql 复制代码
-- 规范化计量数据精度
SELECT ts,
       TRUNCATE(voltage, 0) AS voltage_std,
       TRUNCATE(current, 2) AS current_std,
       TRUNCATE(power, 2) AS power_std,
       TRUNCATE(phase, 1) AS phase_std
FROM meters
WHERE ts >= '2024-01-01 10:00:00'
ORDER BY ts
LIMIT 10;

应用价值

  • 统一数据精度标准
  • 提高数据对比准确性
  • 减少存储空间

示例 12: 异常值过滤

目的:通过截断处理消除测量微小抖动,识别真正的异常值。

sql 复制代码
-- 截断后检测异常值
SELECT ts,
       power AS power_raw,
       TRUNCATE(power, 0) AS power_truncated,
       ABS(power - TRUNCATE(power, 0)) AS decimal_part
FROM meters
WHERE ABS(power - TRUNCATE(power, 0)) > 0.9
ORDER BY ts;

应用价值

  • 过滤测量噪声
  • 识别真实异常
  • 提高数据质量

生产场景应用与目的

场景 A: 电费计算与结算

目的:在电费计算中,需要按照国家标准将用电量截断到指定精度(通常是2位小数),确保计费的一致性和准确性。

示例

sql 复制代码
-- 生成月度电费账单
SELECT location,
       TRUNCATE(SUM(power) * 0.001, 2) AS total_kwh_billing,
       TRUNCATE(SUM(power) * 0.001, 2) * 0.588 AS total_amount
FROM meters
WHERE ts >= '2024-01-01 00:00:00'
  AND ts < '2024-02-01 00:00:00'
GROUP BY location;

场景 B: 负载分级管理

目的:将功率按百位或千位截断,实现负载的粗粒度分级管理,指导需求响应和负荷调度。

示例

sql 复制代码
-- 统计不同功率级别的数据量
SELECT location,
       TRUNCATE(power, -3) AS power_class_1000,
       COUNT(*) AS sample_count
FROM meters
WHERE ts >= NOW - 1d
GROUP BY location, TRUNCATE(power, -3)
ORDER BY location, power_class_1000;

场景 C: 数据压缩与归档

目的:对历史数据进行精度压缩,通过截断小数位降低存储空间,同时保留主要特征。

示例

sql 复制代码
-- 生成压缩后的历史数据
SELECT _wstart AS time_window,
       location,
       TRUNCATE(AVG(voltage), 0) AS avg_voltage,
       TRUNCATE(AVG(current), 1) AS avg_current,
       TRUNCATE(AVG(power), 1) AS avg_power,
       TRUNCATE(AVG(phase), 0) AS avg_phase
FROM meters
WHERE ts >= NOW - 30d
PARTITION BY location
INTERVAL(1h);

场景 D: 告警阈值稳定化

目的:通过截断处理消除测量微小波动,避免频繁触发告警,提高告警系统的稳定性。

示例

sql 复制代码
-- 基于截断值的稳定告警
SELECT ts,
       tbname,
       current AS current_raw,
       TRUNCATE(current, 1) AS current_stable,
       CASE
         WHEN TRUNCATE(current, 1) > 15.0 THEN '严重超载'
         WHEN TRUNCATE(current, 1) > 12.0 THEN '超载告警'
         WHEN TRUNCATE(current, 1) < 5.0 THEN '负载过低'
         ELSE '正常'
       END AS alarm_level
FROM meters
WHERE TRUNCATE(current, 1) NOT BETWEEN 5.0 AND 12.0
  AND ts >= NOW - 1h
ORDER BY ts DESC;

场景 E: 数据展示与可视化

目的:在数据可视化和报表展示时,截断数据到合适精度,提高可读性和美观度。

示例

sql 复制代码
-- 生成可视化展示数据
SELECT _wstart AS time_window,
       TRUNCATE(AVG(voltage), 0) AS voltage,
       TRUNCATE(AVG(current), 2) AS current,
       TRUNCATE(AVG(power), 2) AS power
FROM meters
WHERE ts >= NOW - 24h
INTERVAL(15m)
ORDER BY time_window;

注意事项

  1. 截断与四舍五入的区别 :TRUNCATE 直接截断,不进行四舍五入。例如 TRUNCATE(3.9, 0) 返回 3.0,而不是 4.0。

  2. 精度限制:由于使用 DOUBLE 和 FLOAT 表示结果,存在浮点精度限制,对于需要高精度的财务计算应特别注意。

  3. 负数截断 :负数截断时的行为与正数一致,例如 TRUNCATE(-8888.88, -1) 返回 -8880.0。

  4. digits 参数范围digits 可以是正数、零或负数,但过大或过小的值可能没有实际意义。

  5. NULL 传播:任一参数为 NULL 时返回 NULL。

  6. 与 ROUND 对比

    • TRUNCATE(3.6, 0) = 3.0(直接截断)
    • ROUND(3.6, 0) = 4.0(四舍五入)
  7. 整数类型输入 :对整数类型字段使用 TRUNCATE 时,digits > 0 不会产生小数位,仍返回整数。


数学关系

  • 基本定义TRUNCATE(x, d) 表示将 x 截断到 d 位小数(d>0)或 d 位整数(d<0)
  • 与 FLOOR 关系 :对于正数,TRUNCATE(x, 0) = FLOOR(x)
  • 与 CEIL 关系 :对于负数,TRUNCATE(x, 0) = CEIL(x)
  • 与 ROUND 对比
    • TRUNCATE(x, d) 直接截断
    • ROUND(x, d) 四舍五入
  • 数学表达
    • TRUNCATE(x, d) = FLOOR(x * 10^d) / 10^d (d≥0,x>0)
    • TRUNCATE(x, d) = FLOOR(x / 10^|d|) * 10^|d| (d<0,x>0)

相关函数

  • ROUND :四舍五入函数,ROUND(x, d) 对 x 进行四舍五入到 d 位
  • CEIL :向上取整函数,CEIL(x) 等价于 TRUNCATE(x, 0) + 1(对正数)
  • FLOOR :向下取整函数,FLOOR(x) 等价于 TRUNCATE(x, 0)(对正数)
  • CAST:类型转换函数,可配合使用进行精度控制

函数意义与实际应用价值

数学意义

TRUNCATE 函数实现了数值的截断操作,是数据精度控制的基本工具。与四舍五入不同,截断操作不引入额外的近似误差,适用于需要保守估计或精确控制精度的场景。

实际应用价值

  1. 计费精度控制

    • 确保计费一致性
    • 避免累积误差
    • 符合行业标准
  2. 数据分级管理

    • 简化数据分类
    • 实现粗粒度统计
    • 支持分级决策
  3. 告警抖动消除

    • 过滤微小波动
    • 稳定告警系统
    • 减少误报
  4. 数据压缩归档

    • 降低存储成本
    • 保留主要特征
    • 加快查询速度
  5. 可视化优化

    • 提高数据可读性
    • 美化展示效果
    • 简化用户理解

本用户手册提供了 TRUNCATE 函数的完整使用说明,特别针对电力系统中的计费结算、负载管理、数据归档等实际需求,所有示例均符合 TDengine 语法规范,方便用户快速上手并应用于生产环境。


关于 TDengine

TDengine 是一款专为物联网、工业互联网等场景设计并优化的大数据平台,其核心模块是高性能、集群开源、云原生、极简的时序数据库。

它能安全高效地将大量设备每天产生的高达 TB 甚至 PB 级的数据进行汇聚、存储、分析和分发,并提供 AI 智能体对数据进行预测与异常检测,提供实时的商业洞察。

相关推荐
鹓于8 小时前
Excel图片批量插入与文件瘦身
java·服务器·数据库
TDengine (老段)8 小时前
TDengine 数据函数 CORR 用户手册
大数据·数据库·物联网·时序数据库·tdengine·1024程序员节
倔强的石头_8 小时前
【金仓数据库】ksql 指南(四) —— 创建与管理表(KingbaseES 数据存储核心)
数据库
赵渝强老师8 小时前
【赵渝强老师】TiDB PD集群存储的信息
数据库·mysql·tidb
老纪的技术唠嗑局9 小时前
分库分表MyCat 架构迁移 OceanBase | 百丽核心财务系统迁移经验总结与问题汇总
数据库·架构·oceanbase
xrkhy14 小时前
微服务之ShardingSphere
数据库·微服务·oracle
隐语SecretFlow14 小时前
【隐语SecretFlow】由蚂蚁集团牵头制定的“隐私保护计算安全分级”IEEE国际标准已正式发布!
大数据·网络·安全
JIngJaneIL15 小时前
停车场管理|停车预约管理|基于Springboot的停车场管理系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·后端·论文·毕设·停车场管理系统
煎蛋学姐15 小时前
SSM儿童福利院管理系统ys9w2d07(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
数据库·ssm 框架·儿童福利院管理系统