TDengine 时序函数 CSUM 用户手册
CSUM 函数用户手册(智能电表场景)- 完整修正版
1. 函数概述
CSUM
是 TDengine 的时间序列函数,用于计算指定列的累计和(Cumulative Sum)。该函数按时间顺序对数值进行累加计算,返回每个时间点的累计总和。
CSUM 函数要求时间线有序,在超级表上使用时必须配合 PARTITION BY tbname 使用。
2. 语法
-- 子表查询(时间线天然有序)
SELECT CSUM(column_name) FROM sub_table [WHERE condition] [ORDER BY ts];-- 超级表查询(必须使用 PARTITION BY tbname)
SELECT CSUM(column_name) FROM super_table
[WHERE condition]
PARTITION BY tbname
[ORDER BY tbname, ts];
参数说明
column_name
:需要计算累计和的数值列,支持所有数值类型- 只接受一个参数,不支持多参数
- 超级表必须使用 PARTITION BY tbname 确保每个子表的时间线有序
返回值说明
- 返回类型:
- 有符号数值类型(TINYINT、SMALLINT、INT、BIGINT、BOOL)→ BIGINT
- 无符号数值类型(UTINYINT、USMALLINT、UINT、UBIGINT)→ UBIGINT
- 浮点数类型(FLOAT、DOUBLE)→ DOUBLE
- 空值处理:NULL 值被忽略,不参与累计计算
- 返回行数:与输入行数相同
3. 函数计算原理与实际意义
3.1 计算过程详解
CSUM 函数按时间序列顺序对数值进行逐行累加:
-- 单个子表示例:功率读数 [100, 200, 150, 300, 250]
-- 对应时间:['10:00', '10:01', '10:02', '10:03', '10:04']SELECT ts, power, CSUM(power) AS cumulative_power
FROM d001
ORDER BY ts;
计算过程:
时间 | 功率 | 累计功率 | 计算过程
10:00 | 100 | 100 | 100
10:01 | 200 | 300 | 100 + 200
10:02 | 150 | 450 | 300 + 150
10:03 | 300 | 750 | 450 + 300
10:04 | 250 | 1000 | 750 + 250
3.2 超级表时间线问题
-- ❌ 错误:直接在超级表上使用(时间线混乱)
SELECT ts, power, CSUM(power) FROM meters ORDER BY ts;-- ✅ 正确:使用 PARTITION BY tbname 确保每个子表时间线有序
SELECT tbname, ts, power, CSUM(power) AS cumulative_power
FROM meters
PARTITION BY tbname
ORDER BY tbname, ts;
4. 智能电表应用场景
基于智能电表数据库结构:
-- 超级表
CREATE STABLE meters (ts TIMESTAMP,voltage FLOAT,current FLOAT,power FLOAT,energy FLOAT
) TAGS (device_id VARCHAR(50),location VARCHAR(50),groupid INT
);-- 子表(每个设备一个子表)
CREATE TABLE d001 USING meters TAGS ('meter001', 'California.SanFrancisco', 1);
CREATE TABLE d002 USING meters TAGS ('meter002', 'California.LosAngles', 1);
4.1 单设备累计用电量统计
-- 方式1:直接查询子表(推荐)
SELECT ts,energy,CSUM(energy) AS total_energy_consumed
FROM d001
WHERE ts >= '2024-09-22 00:00:00'
ORDER BY ts;-- 方式2:通过超级表查询特定设备
SELECT ts,energy,CSUM(energy) AS total_energy_consumed
FROM meters
WHERE device_id = 'meter001'AND ts >= '2024-09-22 00:00:00'
PARTITION BY tbname
ORDER BY ts;
4.2 多设备累计分析
-- 所有设备的累计功率分析
SELECT tbname,device_id,ts,power,CSUM(power) AS cumulative_power
FROM meters
WHERE ts >= NOW() - 12h
PARTITION BY tbname
ORDER BY tbname, ts;
4.3 按区域分组累计分析
-- 按区域统计各设备累计用电
SELECT tbname,location,ts,energy,CSUM(energy) AS device_cumulative_energy
FROM meters
WHERE location = 'California.SanFrancisco'AND ts >= NOW() - 24h
PARTITION BY tbname
ORDER BY tbname, ts;
4.4 异常累积检测
-- 检测各设备异常用电的累积情况
SELECT tbname,device_id,ts,power,CSUM(CASE WHEN power > 5000 THEN power ELSE 0 END) AS abnormal_power_cumulative,CSUM(power) AS total_power_cumulative
FROM meters
WHERE ts >= NOW() - 24h
PARTITION BY tbname
ORDER BY tbname, ts;
4.5 累积阈值监控
-- 各设备累积用电量超过阈值监控
SELECT tbname,device_id,ts,CSUM(energy) AS cumulative_energy,CASE WHEN CSUM(energy) > 1000 THEN '超出限额'WHEN CSUM(energy) > 800 THEN '接近限额'ELSE '正常范围'END AS status
FROM meters
WHERE ts >= '2024-09-22 00:00:00'
PARTITION BY tbname
ORDER BY tbname, ts;
4.6 条件累积计算
-- 各设备正常功率范围的累积计算
SELECT tbname,device_id,ts,power,CSUM(CASE WHEN power BETWEEN 1000 AND 5000 THEN power ELSE 0 END) AS normal_power_cumulative,CSUM(power) AS total_cumulative
FROM meters
WHERE ts >= NOW() - 12h
PARTITION BY tbname
ORDER BY tbname, ts;
5. 使用注意事项
5.1 超级表使用限制
-- ❌ 错误:直接在超级表上使用 CSUM(时间线混乱)
SELECT ts, power, CSUM(power) FROM meters ORDER BY ts;-- ❌ 错误:按非子表字段分区
SELECT ts, power, CSUM(power) FROM meters PARTITION BY device_id ORDER BY ts;-- ✅ 正确:使用 PARTITION BY tbname
SELECT tbname, ts, power, CSUM(power) FROM meters
PARTITION BY tbname
ORDER BY tbname, ts;-- ✅ 正确:直接查询子表
SELECT ts, power, CSUM(power) FROM d001 ORDER BY ts;
5.2 数据类型限制
-- ✅ 支持的数据类型
SELECT CSUM(power) FROM d001; -- FLOAT → DOUBLE
SELECT CSUM(current) FROM d001; -- FLOAT → DOUBLE
SELECT CSUM(groupid) FROM meters PARTITION BY tbname; -- INT → BIGINT-- ❌ 不支持的数据类型
SELECT CSUM(device_id) FROM meters PARTITION BY tbname; -- 字符串不支持
SELECT CSUM(ts) FROM meters PARTITION BY tbname; -- 时间戳不支持
5.3 语法限制
-- ❌ 错误用法
SELECT CSUM() FROM meters; -- 无参数
SELECT CSUM(power, current) FROM meters; -- 多参数
SELECT CSUM(AVG(current)) FROM meters; -- 嵌套聚合-- ✅ 正确用法
SELECT CSUM(power) FROM d001 ORDER BY ts; -- 子表查询
SELECT CSUM(power) FROM meters PARTITION BY tbname; -- 超级表查询
5.4 性能优化建议
-- 推荐:查询特定子表
SELECT ts, CSUM(power) FROM d001
WHERE ts >= NOW() - 24h
ORDER BY ts;-- 推荐:超级表查询时限制条件
SELECT tbname, ts, CSUM(power) FROM meters
WHERE ts >= NOW() - 24h AND location = 'California.SanFrancisco'
PARTITION BY tbname
ORDER BY tbname, ts;-- 避免:大范围无限制查询
SELECT CSUM(power) FROM meters PARTITION BY tbname; -- 可能影响性能
6. 子表 vs 超级表查询对比
6.1 子表查询(推荐单设备分析)
-- 单个设备累积分析(性能最佳)
SELECT ts,power,CSUM(power) AS cumulative_power
FROM d001
WHERE ts >= NOW() - 24h
ORDER BY ts;
优势:
- 时间线天然有序,无需 PARTITION BY
- 查询性能最佳
- 适合单设备详细分析
6.2 超级表查询(多设备对比分析)
-- 多个设备累积对比分析
SELECT tbname,device_id,ts,power,CSUM(power) AS cumulative_power
FROM meters
WHERE ts >= NOW() - 24hAND location = 'California.SanFrancisco'
PARTITION BY tbname
ORDER BY tbname, ts;
优势:
- 可以同时分析多个设备
- 便于设备间对比
- 支持按标签过滤
注意:
- 必须使用 PARTITION BY tbname
- 性能相对较低
7. 常见错误及解决方案
7.1 超级表使用错误
-- ❌ 错误:时间线混乱
SELECT ts, power, CSUM(power) FROM meters ORDER BY ts;
-- 问题:不同子表的数据混在一起,时间线不连续-- ✅ 解决:使用 PARTITION BY tbname
SELECT tbname, ts, power, CSUM(power) FROM meters
PARTITION BY tbname
ORDER BY tbname, ts;
7.2 分区字段错误
-- ❌ 错误:按标签字段分区
SELECT device_id, ts, power, CSUM(power) FROM meters
PARTITION BY device_id
ORDER BY device_id, ts;-- ✅ 正确:按子表名分区
SELECT tbname, device_id, ts, power, CSUM(power) FROM meters
PARTITION BY tbname
ORDER BY tbname, ts;
7.3 结果解析示例
-- 超级表查询示例
SELECT tbname,device_id,ts,power,CSUM(power) AS cumulative_power
FROM meters
WHERE ts BETWEEN '2024-09-22 10:00:00' AND '2024-09-22 10:05:00'
PARTITION BY tbname
ORDER BY tbname, ts;
返回结果:
tbname | device_id | ts | power | cumulative_power
d001 | meter001 | 2024-09-22 10:00:00 | 1000 | 1000
d001 | meter001 | 2024-09-22 10:01:00 | 1500 | 2500
d001 | meter001 | 2024-09-22 10:02:00 | 1200 | 3700
d002 | meter002 | 2024-09-22 10:00:00 | 800 | 800
d002 | meter002 | 2024-09-22 10:01:00 | 900 | 1700
d002 | meter002 | 2024-09-22 10:02:00 | 1100 | 2800
**说明:**每个子表(tbname)的累积值是独立计算的,d001 和 d002 各自维护自己的累积序列。
8. 总结
CSUM 函数在智能电表监控系统中的使用要点:
关键特性
- 时序依赖:必须保证时间线有序才能正确累积
- 分区要求:超级表查询必须使用 PARTITION BY tbname
- 子表优先:单设备分析优先直接查询子表
- NULL处理:智能忽略NULL值,保持累积连续性
应用场景选择
- 单设备分析:直接查询子表,性能最佳
- 多设备对比:超级表 + PARTITION BY tbname
- 实时监控:子表查询,响应速度快
- 历史统计:超级表查询,支持复杂过滤
最佳实践
- 优先使用子表:单设备累积分析直接查询子表
- 正确分区:超级表查询必须 PARTITION BY tbname
- 合理排序:ORDER BY tbname, ts 确保结果有序
- 限制范围:使用 WHERE 条件限制时间和标签范围
- 避免混用:不要在需要累积的场景中混合不同子表的时间线
通过正确理解和使用 CSUM 函数的分区要求,可以为智能电表系统提供准确可靠的累积趋势分析能力。
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。