TDengine 字符串函数 CONCAT_WS 用户手册

CONCAT_WS 函数

功能说明

CONCAT_WS 函数用于将多个字符串使用指定的分隔符连接成一个字符串。函数名称中的 "WS" 代表 "With Separator"(带分隔符)。

语法

sql 复制代码
CONCAT_WS(separator, string1, string2, ...)

参数说明

  • separator : 分隔符,用于连接各个字符串,可以是 VARCHARNCHAR 类型
  • string1, string2, ... : 待连接的字符串,可以是 VARCHARNCHAR 类型
  • 参数数量:最少 3 个参数(1 个分隔符 + 2 个待连接字符串),最多 9 个参数(1 个分隔符 + 8 个待连接字符串)

返回值类型

  • 如果任意一个参数为 NCHAR 类型,则返回 NCHAR 类型
  • 否则返回 VARCHAR 类型
  • 返回字符串的最大长度受限于系统最大字段长度

嵌套子查询支持

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

适用于

表和超级表。

使用规则

  1. 分隔符位置: 第一个参数必须是分隔符
  2. 类型提升 : 如果参数中包含 NCHAR 类型,结果会自动提升为 NCHAR 类型
  3. 字符集转换 : VARCHARNCHAR 混用时,VARCHAR 会被转换为 NCHAR,字节数会相应增加
  4. NULL 值处理 :
    • 如果分隔符为 NULL,结果为 NULL
    • 其他参数为 NULL 时会被跳过(不参与连接)
  5. 使用限制: 只能与普通列,选择(Selection)、投影(Projection)函数一起使用,不能与聚合(Aggregation)函数一起使用

智能电表应用示例

场景 1: 生成设备标识字符串

目的: 为每个智能电表创建唯一的、易读的设备标识,方便运维人员识别和管理

sql 复制代码
-- 智能电表表结构
CREATE STABLE meters (
  ts TIMESTAMP,
  current FLOAT,
  voltage INT,
  phase FLOAT,
  power DOUBLE,
  device_id VARCHAR(64),
  region VARCHAR(32),
  status_msg VARCHAR(128)
) TAGS (
  groupid INT,
  location VARCHAR(64)
);

-- 生成完整的设备位置标识
SELECT 
    CONCAT_WS('-', region, location, device_id) AS full_device_id,
    LAST(ts) AS last_update,
    AVG(power) AS avg_power
FROM meters
WHERE ts >= NOW - 1h
GROUP BY groupid, region, location, device_id
ORDER BY avg_power DESC;

结果示例:

复制代码
full_device_id                        | last_update         | avg_power
-------------------------------------------------------------------------
华东-上海办公楼10层1001室-M10001      | 2025-11-07 14:30:00 | 2.35
华东-上海办公楼10层1002室-M10002      | 2025-11-07 14:30:00 | 1.89
华北-北京数据中心3层机房A-M20015      | 2025-11-07 14:30:00 | 15.67

场景 2: 生成告警信息描述

目的: 将多个字段组合成可读的告警描述,便于告警通知和日志记录

sql 复制代码
-- 生成电压异常告警信息
SELECT 
    ts,
    device_id,
    CONCAT_WS(' | ', 
        CASE 
            WHEN voltage > 240 THEN '告警:电压过高'
            WHEN voltage < 210 THEN '告警:电压过低'
            ELSE '正常'
        END,
        region,
        location,
        CONCAT('当前电压:', CAST(voltage AS VARCHAR(10)), 'V'),
        status_msg
    ) AS alert_message
FROM meters
WHERE ts >= NOW - 1d
  AND (voltage > 240 OR voltage < 210)
ORDER BY ts DESC
LIMIT 20;

结果示例:

复制代码
ts                  | device_id | alert_message
------------------------------------------------------------------------------------
2025-11-07 14:25:00 | M10001    | 告警:电压过高 | 华东 | 上海办公楼10层1001室 | 当前电压:245V | 设备运行异常
2025-11-07 14:15:00 | M10032    | 告警:电压过低 | 华东 | 上海办公楼8层801室 | 当前电压:205V | 负载过大
2025-11-07 14:10:00 | M20015    | 告警:电压过高 | 华北 | 北京数据中心3层机房A | 当前电压:242V | 正常运行

场景 3: 生成CSV格式的数据导出

目的: 将电表数据导出为CSV格式,方便与第三方系统集成或进行数据分析

sql 复制代码
-- 导出每小时电表数据摘要(CSV格式)
SELECT 
    CONCAT_WS(',',
        TO_ISO8601(ts),
        device_id,
        region,
        location,
        CAST(AVG(voltage) AS VARCHAR(10)),
        CAST(AVG(current) AS VARCHAR(20)),
        CAST(AVG(power) AS VARCHAR(20)),
        CAST(SUM(power)/1000 AS VARCHAR(20))  -- 转换为kWh
    ) AS csv_line
FROM meters
WHERE ts >= NOW - 24h
INTERVAL(1h)
ORDER BY ts;

结果示例:

复制代码
csv_line
------------------------------------------------------------------------------------
2025-11-07T09:00:00+08:00,M10001,华东,上海办公楼10层1001室,220,10.2,2.25,2.25
2025-11-07T10:00:00+08:00,M10001,华东,上海办公楼10层1001室,221,10.5,2.32,2.32
2025-11-07T11:00:00+08:00,M10001,华东,上海办公楼10层1001室,222,10.3,2.28,2.28

场景 4: 生成运维工单描述

目的: 自动生成包含完整信息的工单描述,提高运维效率

sql 复制代码
-- 生成需要维护的电表工单信息
SELECT 
    device_id,
    CONCAT_WS(' - ',
        '设备ID:' || device_id,
        '位置:' || region || '/' || location,
        '问题:电压不稳定',
        '统计周期:最近24小时',
        '电压范围:' || CAST(MIN(voltage) AS VARCHAR(10)) || 'V~' || CAST(MAX(voltage) AS VARCHAR(10)) || 'V',
        '异常次数:' || CAST(COUNT(*) AS VARCHAR(10)),
        '建议:现场检查线路'
    ) AS work_order
FROM meters
WHERE ts >= NOW - 24h
  AND (voltage < 210 OR voltage > 240)
GROUP BY device_id, region, location
HAVING COUNT(*) > 10
ORDER BY COUNT(*) DESC;

结果示例:

复制代码
device_id | work_order
------------------------------------------------------------------------------------
M10001    | 设备ID:M10001 - 位置:华东/上海办公楼10层1001室 - 问题:电压不稳定 - 统计周期:最近24小时 - 电压范围:205V~245V - 异常次数:45 - 建议:现场检查线路
M10032    | 设备ID:M10032 - 位置:华东/上海办公楼8层801室 - 问题:电压不稳定 - 统计周期:最近24小时 - 电压范围:208V~242V - 异常次数:32 - 建议:现场检查线路

场景 5: 生成能耗报告摘要

目的: 创建易读的能耗分析报告,支持多维度查看

sql 复制代码
-- 按区域生成能耗摘要报告
SELECT 
    region,
    CONCAT_WS(' | ',
        '总用电量:' || CAST(ROUND(SUM(power)/1000, 2) AS VARCHAR(20)) || 'kWh',
        '平均功率:' || CAST(ROUND(AVG(power), 2) AS VARCHAR(20)) || 'kW',
        '峰值功率:' || CAST(ROUND(MAX(power), 2) AS VARCHAR(20)) || 'kW',
        '平均电压:' || CAST(ROUND(AVG(voltage), 0) AS VARCHAR(10)) || 'V',
        '设备数量:' || CAST(COUNT(DISTINCT device_id) AS VARCHAR(10))
    ) AS energy_summary
FROM meters
WHERE ts >= NOW - 30d
GROUP BY region
ORDER BY SUM(power) DESC;

结果示例:

复制代码
region | energy_summary
------------------------------------------------------------------------------------
华东   | 总用电量:125680.50kWh | 平均功率:2.35kW | 峰值功率:18.90kW | 平均电压:221V | 设备数量:156
华北   | 总用电量:98450.25kWh | 平均功率:3.12kW | 峰值功率:22.50kW | 平均电压:220V | 设备数量:98
华南   | 总用电量:87320.80kWh | 平均功率:2.88kW | 峰值功率:19.50kW | 平均电压:222V | 设备数量:112

场景 6: 生成设备状态标签

目的: 为监控大屏或仪表盘生成包含多个状态信息的标签

sql 复制代码
-- 生成实时设备状态标签
SELECT 
    device_id,
    region,
    location,
    CONCAT_WS(' · ',
        CASE 
            WHEN voltage BETWEEN 210 AND 240 THEN '✓电压正常'
            ELSE '✗电压异常'
        END,
        CASE 
            WHEN power < 5 THEN '负载低'
            WHEN power < 10 THEN '负载中'
            ELSE '负载高'
        END,
        CASE 
            WHEN phase BETWEEN -15 AND 15 THEN '功率因数正常'
            ELSE '功率因数异常'
        END,
        CAST(ROUND(power, 1) AS VARCHAR(10)) || 'kW'
    ) AS status_label,
    ts
FROM meters
WHERE ts >= NOW - 5m
ORDER BY power DESC
LIMIT 10;

结果示例:

复制代码
device_id | region | location           | status_label                      | ts
-------------------------------------------------------------------------------------------------
M20015    | 华北   | 北京数据中心3层机房A | ✓电压正常 · 负载高 · 功率因数正常 · 18.5kW | 2025-11-07 14:30:00
M10032    | 华东   | 上海办公楼8层801室  | ✓电压正常 · 负载高 · 功率因数正常 · 16.2kW | 2025-11-07 14:30:00
M10008    | 华东   | 上海办公楼5层501室  | ✗电压异常 · 负载中 · 功率因数异常 · 12.8kW | 2025-11-07 14:30:00

场景 7: 生成设备维护记录

目的: 根据设备运行状态自动生成维护建议记录

sql 复制代码
-- 生成设备健康状况报告
SELECT 
    device_id,
    location,
    CONCAT_WS('\n',
        '=== 设备健康报告 ===',
        '设备编号: ' || device_id,
        '安装位置: ' || region || ' - ' || location,
        '数据时间: ' || TO_ISO8601(LAST(ts)),
        '--- 电能质量 ---',
        '电压: ' || CAST(LAST(voltage) AS VARCHAR(10)) || 'V',
        '电流: ' || CAST(ROUND(LAST(current), 2) AS VARCHAR(10)) || 'A',
        '功率: ' || CAST(ROUND(LAST(power), 2) AS VARCHAR(10)) || 'kW',
        '相位角: ' || CAST(ROUND(LAST(phase), 2) AS VARCHAR(10)) || '°',
        '--- 运行状态 ---',
        status_msg
    ) AS health_report
FROM meters
WHERE groupid = 1
GROUP BY device_id, region, location
ORDER BY device_id;

结果示例:

复制代码
device_id | location           | health_report
-------------------------------------------------------------------------------------------------
M10001    | 上海办公楼10层1001室 | === 设备健康报告 ===
          |                    | 设备编号: M10001
          |                    | 安装位置: 华东 - 上海办公楼10层1001室
          |                    | 数据时间: 2025-11-07T14:30:00+08:00
          |                    | --- 电能质量 ---
          |                    | 电压: 221V
          |                    | 电流: 10.52A
          |                    | 功率: 2.32kW
          |                    | 相位角: 5.2°
          |                    | --- 运行状态 ---
          |                    | 设备运行正常

CONCAT_WS 与 CONCAT 函数的区别

1. 分隔符处理

CONCAT 函数:

sql 复制代码
-- CONCAT 直接连接,无分隔符
SELECT CONCAT(region, location, device_id) AS result
FROM meters
LIMIT 1;

结果 : 华东上海办公楼10层1001室M10001 (字符串直接拼接,无分隔符)

CONCAT_WS 函数:

sql 复制代码
-- CONCAT_WS 使用指定分隔符连接
SELECT CONCAT_WS('-', region, location, device_id) AS result
FROM meters
LIMIT 1;

结果 : 华东-上海办公楼10层1001室-M10001 (使用 - 作为分隔符)

2. NULL 值处理

CONCAT 函数:

sql 复制代码
-- 插入测试数据(status_msg 为 NULL)
INSERT INTO meters_test VALUES (NOW, 10.5, 220, 5.0, 2.3, 'M10001', '华东', NULL);

-- CONCAT 遇到 NULL 返回 NULL
SELECT CONCAT(region, '-', location, '-', status_msg) AS result
FROM meters_test;

结果 : NULL (任一参数为 NULL,整个结果为 NULL)

CONCAT_WS 函数:

sql 复制代码
-- CONCAT_WS 自动跳过 NULL 值
SELECT CONCAT_WS('-', region, location, status_msg) AS result
FROM meters_test;

结果 : 华东-上海办公楼10层1001室 (自动跳过 NULL 值的 status_msg)

3. 参数数量

CONCAT 函数:

  • 最少 2 个参数
  • 最多无限制(取决于系统限制)

CONCAT_WS 函数:

  • 最少 3 个参数(1 个分隔符 + 2 个字符串)
  • 最多 9 个参数(1 个分隔符 + 8 个字符串)

4. 使用场景对比

场景 CONCAT CONCAT_WS 推荐
简单拼接固定格式 CONCAT('设备:', device_id) CONCAT_WS(':', '设备', device_id) CONCAT
需要统一分隔符 CONCAT(region, '-', location, '-', device_id) CONCAT_WS('-', region, location, device_id) CONCAT_WS
可能有 NULL 值 结果为 NULL 自动跳过 NULL CONCAT_WS
生成 CSV 格式 需要手动添加逗号 CONCAT_WS(',', col1, col2, col3) CONCAT_WS
路径拼接 需要手动添加分隔符 CONCAT_WS('/', region, building, floor) CONCAT_WS

5. 实际示例对比

sql 复制代码
-- 场景:生成设备完整信息,某些字段可能为 NULL

-- 使用 CONCAT(不推荐,遇到 NULL 会失败)
SELECT 
    device_id,
    CONCAT(region, '-', location, '-', status_msg, '-', CAST(groupid AS VARCHAR(10))) AS info
FROM meters
WHERE device_id = 'M10001';
-- 如果 status_msg 为 NULL,整个结果为 NULL

-- 使用 CONCAT_WS(推荐,自动跳过 NULL)
SELECT 
    device_id,
    CONCAT_WS('-', region, location, status_msg, CAST(groupid AS VARCHAR(10))) AS info
FROM meters
WHERE device_id = 'M10001';
-- 如果 status_msg 为 NULL,结果为: 华东-上海办公楼10层1001室-1

6. 性能考虑

  • CONCAT: 由于需要手动添加分隔符,参数数量较多时代码冗长
  • CONCAT_WS: 代码简洁,但有参数数量限制(最多8个待连接字符串)

总结

  • 使用 CONCAT 的场景:

    • 简单的字符串拼接
    • 不需要统一分隔符
    • 确定所有字段都不为 NULL
    • 需要超过 8 个字段拼接
  • 使用 CONCAT_WS 的场景:

    • 需要统一分隔符连接多个字段
    • 字段可能包含 NULL 值,且希望跳过 NULL
    • 生成 CSV、路径等格式化字符串
    • 代码简洁性要求高

注意事项

  1. 参数限制: CONCAT_WS 最多支持 8 个待连接的字符串(加上分隔符共 9 个参数)
  2. 结果长度: 连接后的字符串长度会随参数数量增加,需注意不要超出系统限制(VARCHAR 最大 16384 字节)
  3. 性能考虑: 连接大量字符串时,会占用相应的内存空间
  4. 字符集: 混用不同字符集时,需要注意字节数的变化
  5. 数值转换 : 在连接数值类型时,需要使用 CAST 函数先转换为字符串类型
  6. 分隔符为 NULL: 如果分隔符本身为 NULL,则整个结果为 NULL

关于 TDengine

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

相关推荐
TTGGGFF2 小时前
人工智能:大语言模型或为死胡同?拆解AI发展的底层逻辑、争议与未来方向
大数据·人工智能·语言模型
IT 小阿姨(数据库)2 小时前
PostgreSQL 之上的开源时序数据库 TimescaleDB 详解
运维·数据库·sql·postgresql·开源·centos·时序数据库
会跑的兔子2 小时前
Android 16 Kotlin协程 第一部分
android·开发语言·kotlin
Meteors.3 小时前
安卓进阶——OpenGL ES
android
熊文豪3 小时前
openEuler 云原生实战:部署高性能 Redis 集群与压测分析
数据库·redis·云原生·openeuler
GTgiantech3 小时前
科普SFP 封装光模块教程
服务器·网络·数据库
深圳市恒讯科技3 小时前
如何在服务器上安装和配置数据库(如MySQL)?
服务器·数据库·mysql
言之。3 小时前
TiDB分布式数据库技术架构概述
数据库·分布式·tidb
杂家4 小时前
Hadoop完全分布式部署(超详细)
大数据·hadoop·分布式