
TO_JSON 函数
函数概述
功能说明: 将 JSON 格式的字符串常量转换为 JSON 类型,主要用于在 SELECT 查询中返回 JSON 类型的常量值。
版本: v3.0.0.0 及以上
返回结果类型: JSON
适用数据类型: VARCHAR、NCHAR 类型的 JSON 格式字符串常量
嵌套子查询支持: 适用于内层查询和外层查询。
适用于: 表和超级表。
语法
sql
TO_JSON(str_literal)
参数说明:
str_literal: JSON 格式的字符串字面量,形如'{ "key" : value }'
JSON TAG 的重要限制
⚠️ 关键约束:
- JSON 类型只能用于 TAGS,不能用于数据列
- JSON TAG 必须是唯一的 TAG,不能与其他类型的 TAG 共存
- 每个超级表只能有一个 JSON TAG
正确的表结构示例
sql
-- ✅ 正确:只有一个 JSON TAG
CREATE STABLE meters (
ts TIMESTAMP,
current FLOAT,
voltage FLOAT,
phase FLOAT
) TAGS (
properties JSON
);
错误的表结构示例
sql
-- ❌ 错误:JSON TAG 不能与其他 TAG 共存
CREATE STABLE meters (
ts TIMESTAMP,
current FLOAT,
voltage FLOAT,
phase FLOAT
) TAGS (
groupid INT, -- 错误:不能有其他 TAG
location VARCHAR(24), -- 错误:不能有其他 TAG
properties JSON
);
-- ❌ 错误:JSON 不能用于数据列
CREATE STABLE meters (
ts TIMESTAMP,
current FLOAT,
properties JSON -- 错误:JSON 只能用于 TAG
) TAGS (
location VARCHAR(24)
);
JSON 字符串格式要求
基本格式
- 必须是有效的 JSON 对象格式,以
{开始,以}结束 - 空 JSON 对象表示为
'{}' - 键(key)必须是字符串字面量,使用双引号包围
- 值(value)可以是:数值、字符串、布尔值、null、嵌套对象、数组
使用说明
-
使用场景:
- TO_JSON 是标量函数,只能在 SELECT 查询中使用
- 用于返回 JSON 类型的常量值
- 不能用于创建表或插入数据
-
格式验证:
- 无效的 JSON 格式会返回 NULL
- 不支持转义符
智能电表示例环境搭建
1. 创建数据库和超级表
sql
-- 创建数据库
CREATE DATABASE IF NOT EXISTS power PRECISION 'ms';
USE power;
-- 创建带 JSON TAG 的超级表(只能有一个 JSON TAG)
CREATE STABLE meters (
ts TIMESTAMP,
current FLOAT,
voltage FLOAT,
phase FLOAT
) TAGS (
properties JSON
);
2. 创建子表(直接使用字符串,无需 TO_JSON)
sql
-- 正确方式:直接使用 JSON 字符串创建子表
-- 所有设备信息都存储在 JSON TAG 中
CREATE TABLE d1001 USING meters TAGS (
'{"groupid":1,"location":"California","model":"TypeA","firmware":"v1.2.3"}'
);
CREATE TABLE d1002 USING meters TAGS (
'{"groupid":2,"location":"New York","model":"TypeB","firmware":"v2.0.1"}'
);
CREATE TABLE d1003 USING meters TAGS (
'{"groupid":3,"location":"Texas","model":"TypeC","firmware":"v3.1.0"}'
);
3. 插入测试数据
sql
-- 插入时序数据
INSERT INTO d1001 VALUES
('2024-01-15 08:00:00.000', 10.2, 220.5, 0.31),
('2024-01-15 14:30:00.000', 11.5, 219.8, 0.33),
('2024-01-15 20:00:00.000', 12.1, 221.2, 0.30);
INSERT INTO d1002 VALUES
('2024-01-15 08:00:00.000', 9.8, 221.0, 0.30),
('2024-01-15 12:00:00.000', 10.4, 220.5, 0.32);
INSERT INTO d1003 VALUES
('2024-01-15 10:00:00.000', 13.5, 217.2, 0.27);
4. 查询 JSON TAG 中的字段
sql
-- 查询设备信息
SELECT
tbname,
properties->'groupid' AS groupid,
properties->'location' AS location,
properties->'model' AS model,
properties->'firmware' AS firmware
FROM meters;
输出示例:
tbname | groupid | location | model | firmware |
===================================================================
d1001 | 1 | "California" | "TypeA" | "v1.2.3" |
d1002 | 2 | "New York" | "TypeB" | "v2.0.1" |
d1003 | 3 | "Texas" | "TypeC" | "v3.1.0" |
TO_JSON 函数的应用场景
场景一: 查询中返回 JSON 常量
sql
-- 为查询结果添加 JSON 格式的元数据
SELECT
ts,
properties->'location' AS location,
current,
voltage,
TO_JSON('{"data_source":"sensor","export_format":"v1.0"}') AS metadata
FROM meters
WHERE ts >= '2024-01-15 00:00:00'
LIMIT 5;
场景二: JSON 格式验证
sql
-- 验证有效 JSON
SELECT TO_JSON('{"status":"ok","code":200}') AS valid_json;
-- 输出: {"status":"ok","code":200}
-- 验证无效 JSON
SELECT TO_JSON('{"invalid}') AS invalid_json;
-- 输出: NULL
场景三: 条件表达式中使用
sql
-- 根据条件返回不同的 JSON 状态
SELECT
ts,
properties->'location' AS location,
current,
CASE
WHEN current > 12 THEN TO_JSON('{"status":"high","alert":true}')
WHEN current < 9.5 THEN TO_JSON('{"status":"low","alert":true}')
ELSE TO_JSON('{"status":"normal","alert":false}')
END AS status_info
FROM meters
ORDER BY ts;
查询 JSON TAG 的常用场景
按 JSON TAG 字段查询
sql
-- 查询特定位置的设备
SELECT
tbname,
properties->'location' AS location,
properties->'model' AS model
FROM meters
WHERE properties->'location' = '"California"';
-- 查询特定型号的设备数据
SELECT
ts,
properties->'model' AS model,
current,
voltage
FROM meters
WHERE properties->'model' = '"TypeA"'
ORDER BY ts;
按 JSON TAG 字段分组统计
sql
-- 按型号统计平均电流
SELECT
properties->'model' AS model,
COUNT(*) AS record_count,
AVG(current) AS avg_current,
AVG(voltage) AS avg_voltage
FROM meters
GROUP BY properties->'model';
-- 按位置统计设备数量
SELECT
properties->'location' AS location,
COUNT(DISTINCT tbname) AS device_count
FROM meters
GROUP BY properties->'location';
注意事项
✅ 正确用法
-
创建表时直接使用字符串
sqlCREATE TABLE d1001 USING meters TAGS ('{"key":"value"}'); -
在 SELECT 中使用 TO_JSON
sqlSELECT TO_JSON('{"key":"value"}') FROM table; -
JSON TAG 必须是唯一的 TAG
sqlCREATE STABLE meters (...) TAGS (properties JSON);
❌ 错误用法
-
不能在创建表时使用 TO_JSON
sql-- ❌ 错误 CREATE TABLE d1001 USING meters TAGS (TO_JSON('{"key":"value"}')); -- ✅ 正确 CREATE TABLE d1001 USING meters TAGS ('{"key":"value"}'); -
JSON TAG 不能与其他 TAG 共存
sql-- ❌ 错误 CREATE STABLE meters (...) TAGS (id INT, properties JSON); -- ✅ 正确:所有信息都放在 JSON 中 CREATE STABLE meters (...) TAGS (properties JSON); -
不能使用列值作为参数
sql-- ❌ 错误 SELECT TO_JSON(column_name) FROM table;
最佳实践
-
JSON TAG 设计原则:
- 由于 JSON TAG 必须是唯一的 TAG,建议将所有设备元数据都存储在 JSON 中
- 常用于查询过滤的字段可以在 JSON 中单独定义为顶层字段
-
JSON 结构示例:
json{ "groupid": 1, "location": "California", "model": "TypeA", "firmware": "v1.2.3", "install_date": "2024-01-10", "config": { "sampling_rate": 1000, "precision": "high" } } -
查询优化:
sql-- 为常用查询字段建立清晰的结构 SELECT properties->'groupid' AS groupid, properties->'location' AS location, properties->'model' AS model FROM meters WHERE properties->'location' = '"California"';
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。