TDengine 时序函数 CSUM 用户手册

CSUM 函数用户手册(智能电表场景)- 完整修正版

1. 函数概述

CSUM 是 TDengine 的时间序列函数,用于计算指定列的累计和(Cumulative Sum)。该函数按时间顺序对数值进行累加计算,返回每个时间点的累计总和。

CSUM 函数要求时间线有序,在超级表上使用时必须配合 PARTITION BY tbname 使用。

2. 语法

sql 复制代码
-- 子表查询(时间线天然有序)
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 函数按时间序列顺序对数值进行逐行累加:

sql 复制代码
-- 单个子表示例:功率读数 [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 超级表时间线问题

sql 复制代码
-- ❌ 错误:直接在超级表上使用(时间线混乱)
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. 智能电表应用场景

基于智能电表数据库结构:

sql 复制代码
-- 超级表
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 单设备累计用电量统计

sql 复制代码
-- 方式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 多设备累计分析

sql 复制代码
-- 所有设备的累计功率分析
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 按区域分组累计分析

sql 复制代码
-- 按区域统计各设备累计用电
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 异常累积检测

sql 复制代码
-- 检测各设备异常用电的累积情况
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 累积阈值监控

sql 复制代码
-- 各设备累积用电量超过阈值监控
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 条件累积计算

sql 复制代码
-- 各设备正常功率范围的累积计算
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 超级表使用限制

sql 复制代码
-- ❌ 错误:直接在超级表上使用 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 数据类型限制

sql 复制代码
-- ✅ 支持的数据类型
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 语法限制

sql 复制代码
-- ❌ 错误用法
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 性能优化建议

sql 复制代码
-- 推荐:查询特定子表
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 子表查询(推荐单设备分析)

sql 复制代码
-- 单个设备累积分析(性能最佳)
SELECT 
    ts,
    power,
    CSUM(power) AS cumulative_power
FROM d001 
WHERE ts >= NOW() - 24h
ORDER BY ts;

优势:

  • 时间线天然有序,无需 PARTITION BY
  • 查询性能最佳
  • 适合单设备详细分析

6.2 超级表查询(多设备对比分析)

sql 复制代码
-- 多个设备累积对比分析
SELECT 
    tbname,
    device_id,
    ts,
    power,
    CSUM(power) AS cumulative_power
FROM meters 
WHERE ts >= NOW() - 24h
  AND location = 'California.SanFrancisco'
PARTITION BY tbname
ORDER BY tbname, ts;

优势:

  • 可以同时分析多个设备
  • 便于设备间对比
  • 支持按标签过滤

注意:

  • 必须使用 PARTITION BY tbname
  • 性能相对较低

7. 常见错误及解决方案

7.1 超级表使用错误

sql 复制代码
-- ❌ 错误:时间线混乱
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 分区字段错误

sql 复制代码
-- ❌ 错误:按标签字段分区
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 结果解析示例

sql 复制代码
-- 超级表查询示例
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 函数在智能电表监控系统中的使用要点:

关键特性

  1. 时序依赖:必须保证时间线有序才能正确累积
  2. 分区要求:超级表查询必须使用 PARTITION BY tbname
  3. 子表优先:单设备分析优先直接查询子表
  4. NULL处理:智能忽略NULL值,保持累积连续性

应用场景选择

  • 单设备分析:直接查询子表,性能最佳
  • 多设备对比:超级表 + PARTITION BY tbname
  • 实时监控:子表查询,响应速度快
  • 历史统计:超级表查询,支持复杂过滤

最佳实践

  1. 优先使用子表:单设备累积分析直接查询子表
  2. 正确分区:超级表查询必须 PARTITION BY tbname
  3. 合理排序:ORDER BY tbname, ts 确保结果有序
  4. 限制范围:使用 WHERE 条件限制时间和标签范围
  5. 避免混用:不要在需要累积的场景中混合不同子表的时间线

通过正确理解和使用 CSUM 函数的分区要求,可以为智能电表系统提供准确可靠的累积趋势分析能力。

关于 TDengine

TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。

相关推荐
lixora2 小时前
postgres linux 环境psql 中文乱码处理
数据库
摇滚侠3 小时前
在 Oracle SQL 中实现 `IF-ELSE` 逻辑 SQL 错误 [12704] [72000]: ORA-12704: 字符集不匹配
数据库·sql·oracle
京东零售技术4 小时前
京东零售胡浩:智能供应链从运筹到大模型到超级智能体的演进
大数据·人工智能
lypzcgf7 小时前
Coze源码分析-资源库-删除数据库-后端源码-流程/核心技术/总结
数据库·go·coze·coze源码分析·智能体平台·ai应用平台·agent平台
土丁爱吃大米饭8 小时前
重磅!Repo Wiki!
大数据·词法分析·语义分析·语法分析·qoder·repo wiki
l1t8 小时前
拉取postgresql 18.0 docker镜像并运行容器
数据库·docker·postgresql
问道飞鱼9 小时前
【大数据技术】ClickHouse配置详细解读
大数据·clickhouse·配置信息
wszysystem9 小时前
UniDac控件关于主从表的创建
数据库
Morpheon9 小时前
SQL窗口函数中的排名函数详解:从基础到高级应用
数据库·sql·mysql