TDengine 字符串函数 LIKE_IN_SET 用户手册

LIKE_IN_SET 函数使用手册
函数定义
LIKE_IN_SET(expr1, expr2[, expr3])
功能说明
一句话描述: 在一个字符串中模糊匹配多个字符串, 找到任何一个即返回匹配到的位置。
将 expr2 以 expr3 为分隔符切分为一个字符串模式列表,将 expr1 使用 LIKE 运算符的语义与列表中的模式进行匹配,返回第一个匹配项的序号,无匹配项则返回 0。
参数说明
| 参数 | 说明 | 类型 | 必填 |
|---|---|---|---|
expr1 | 待匹配的字符串 | VARCHAR、NCHAR | 是 |
expr2 | 模式列表(用分隔符分隔) | VARCHAR、NCHAR | 是 |
expr3 | 分隔符(默认为 ,) | VARCHAR、NCHAR | 否 |
说明:
expr3不可以是 NULL 或空串- 支持 LIKE 通配符:
%(匹配任意字符) 和_(匹配单个字符)
返回值
- 类型: BIGINT
- 返回: 第一个匹配模式在列表中的位置(从 1 开始)
- 无匹配: 返回 0
- NULL 值: 如果
expr1或expr2为 NULL,返回 NULL
适用范围
- 数据类型: VARCHAR、NCHAR
- 适用于: 表和超级表
- 子查询: 支持内层和外层查询
与 FIND_IN_SET 的区别
| 特性 | LIKE_IN_SET | FIND_IN_SET |
|---|---|---|
| 匹配方式 | 模糊匹配(支持 % 和 _ 通配符) | 精确匹配 |
| 适用场景 | 需要模式匹配、前缀/后缀匹配 | 需要完全相等匹配 |
| 性能 | 较慢(需要正则匹配) | 较快(字符串比较) |
| 示例 | 'abc' 匹配 'ab%' ✅ | 'abc' 匹配 'ab%' ❌ |
对比示例:
-- FIND_IN_SET: 精确匹配
SELECT FIND_IN_SET('Beijing-A1', 'Beijing,Shanghai,Guangzhou');
-- 返回: 0 (无精确匹配)-- LIKE_IN_SET: 模糊匹配
SELECT LIKE_IN_SET('Beijing-A1', 'Beijing%,Shanghai%,Guangzhou%');
-- 返回: 1 (匹配 'Beijing%' 模式)
使用场景示例
场景 1: 智能电表区域筛选
业务需求: 从设备位置信息中快速筛选特定区域的电表
-- 创建智能电表超级表
CREATE STABLE test.meters (`ts` TIMESTAMP,`current` FLOAT,`voltage` INT,`phase` FLOAT
) TAGS (`groupid` INT,`location` VARCHAR(100)
);-- 插入测试数据
INSERT INTO test.d001 USING test.meters TAGS(1, 'Beijing-Chaoyang-Building-A-Floor-10')
VALUES ('2024-01-15 08:00:00', 10.5, 220, 0.85);INSERT INTO test.d002 USING test.meters TAGS(2, 'Shanghai-Pudong-Tower-B-Floor-20')
VALUES ('2024-01-15 08:00:00', 12.3, 221, 0.88);INSERT INTO test.d003 USING test.meters TAGS(3, 'Guangzhou-Tianhe-Plaza-C-Floor-15')
VALUES ('2024-01-15 08:00:00', 9.8, 219, 0.82);INSERT INTO test.d004 USING test.meters TAGS(4, 'Beijing-Haidian-Park-D-Floor-5')
VALUES ('2024-01-15 08:00:00', 11.2, 222, 0.90);INSERT INTO test.d005 USING test.meters TAGS(5, 'Shenzhen-Nanshan-Center-E-Floor-30')
VALUES ('2024-01-15 08:00:00', 10.8, 220, 0.87);-- 查询: 筛选北京和上海区域的电表
SELECT tbname,location,voltage,current,LIKE_IN_SET(location, 'Beijing%,Shanghai%') as region_match_index
FROM test.meters
WHERE LIKE_IN_SET(location, 'Beijing%,Shanghai%') > 0;
输出示例:
tbname | location | voltage | current | region_match_index
-------|---------------------------------------------|---------|---------|-------------------
d001 | Beijing-Chaoyang-Building-A-Floor-10 | 220 | 10.5 | 1
d002 | Shanghai-Pudong-Tower-B-Floor-20 | 221 | 12.3 | 2
d004 | Beijing-Haidian-Park-D-Floor-5 | 222 | 11.2 | 1
目的: 快速定位特定区域设备,替代多个 OR 条件的复杂查询
场景 2: 建筑类型分类统计
业务需求: 统计不同建筑类型的电表数量和用电情况
-- 按建筑类型分类统计
SELECT building_type,COUNT(*) as meter_count,ROUND(AVG(voltage), 2) as avg_voltage,ROUND(AVG(current), 2) as avg_current
FROM (SELECT CASE WHEN LIKE_IN_SET(location, '%Building%,%Tower%') = 1 THEN 'Office Building'WHEN LIKE_IN_SET(location, '%Building%,%Tower%') = 2 THEN 'High-rise Tower'WHEN LIKE_IN_SET(location, '%Plaza%,%Center%,%Park%') > 0 THEN 'Commercial Complex'ELSE 'Other'END as building_type,voltage,currentFROM test.meters
) AS subquery
GROUP BY building_type;
输出示例:
building_type | meter_count | avg_voltage | avg_current
-------------------|-------------|-------------|-------------
Office Building | 1 | 220.00 | 10.50
High-rise Tower | 1 | 221.00 | 12.30
Commercial Complex | 3 | 220.33 | 10.60
目的: 实现灵活的多条件分类,便于业务分析
场景 3: 楼层范围筛选
业务需求: 筛选特定楼层范围的电表进行巡检
-- 筛选 5-20 层的电表
SELECT tbname,location,voltage,LIKE_IN_SET(location, '%Floor-5%,%Floor-1_%,%Floor-20%') as floor_match
FROM test.meters
WHERE LIKE_IN_SET(location, '%Floor-5%,%Floor-1_%,%Floor-20%') > 0
ORDER BY location;
输出示例:
tbname | location | voltage | floor_match
-------|---------------------------------------|---------|------------
d001 | Beijing-Chaoyang-Building-A-Floor-10 | 220 | 2
d003 | Guangzhou-Tianhe-Plaza-C-Floor-15 | 219 | 2
d004 | Beijing-Haidian-Park-D-Floor-5 | 222 | 1
d002 | Shanghai-Pudong-Tower-B-Floor-20 | 221 | 3
目的: 支持复杂的楼层范围查询,用于设备维护计划
场景 4: 异常设备定位
业务需求: 快速定位特定区域的异常电压设备
-- 查找北上广深异常电压的电表
SELECT tbname,location,voltage,current,CASE WHEN voltage > 230 THEN 'High Voltage'WHEN voltage < 210 THEN 'Low Voltage'ELSE 'Normal'END as voltage_status
FROM test.meters
WHERE LIKE_IN_SET(location, 'Beijing%,Shanghai%,Guangzhou%,Shenzhen%') > 0AND (voltage > 230 OR voltage < 210);
目的: 结合区域和状态条件,实现精准告警
场景 5: 设备名称规范检查
业务需求: 检查位置信息是否符合命名规范
-- 检查位置信息格式是否规范
SELECT tbname,location,CASE WHEN LIKE_IN_SET(location, '%-%-%-%-%') > 0 THEN 'Standard Format'ELSE 'Non-standard Format'END as format_status,LENGTH(location) as location_length
FROM test.meters;
输出示例:
tbname | location | format_status | location_length
-------|---------------------------------------------|--------------------|----------------
d001 | Beijing-Chaoyang-Building-A-Floor-10 | Standard Format | 40
d002 | Shanghai-Pudong-Tower-B-Floor-20 | Standard Format | 36
d003 | Guangzhou-Tianhe-Plaza-C-Floor-15 | Standard Format | 37
d004 | Beijing-Haidian-Park-D-Floor-5 | Standard Format | 34
d005 | Shenzhen-Nanshan-Center-E-Floor-30 | Standard Format | 38
目的: 数据质量监控,确保位置信息符合标准格式
实际应用优势
1. 简化查询语句
传统方式:
SELECT * FROM test.meters
WHERE location LIKE 'Beijing%' OR location LIKE 'Shanghai%' OR location LIKE 'Guangzhou%';
使用 LIKE_IN_SET:
SELECT * FROM test.meters
WHERE LIKE_IN_SET(location, 'Beijing%,Shanghai%,Guangzhou%') > 0;
2. 动态模式列表
-- 模式列表可以来自变量或配置
SET @regions = 'Beijing%,Shanghai%,Shenzhen%';
SELECT * FROM test.meters
WHERE LIKE_IN_SET(location, @regions) > 0;
3. 优先级匹配
-- 返回值表示匹配的优先级
SELECT tbname,location,LIKE_IN_SET(location, 'Beijing-Chaoyang%,Beijing%,Shanghai%') as priority
FROM test.meters
ORDER BY priority; -- 按匹配优先级排序
性能建议
- 避免通配符开头:
'%keyword'无法使用索引 - 控制模式数量: 建议单次查询不超过 20 个模式
- 优先使用 FIND_IN_SET: 如果可以精确匹配,性能更好
- 合理使用分隔符: 避免分隔符与数据内容冲突
注意事项
- 大小写敏感: 匹配时区分大小写
- NULL 处理: 任何参数为 NULL 都返回 NULL
- 通配符转义: 如需匹配
%或_字符本身,需要转义 - 分隔符限制: 分隔符不能为 NULL 或空字符串
相关函数
FIND_IN_SET(): 精确匹配版本REGEXP_IN_SET(): 正则表达式匹配版本LIKE: 单模式模糊匹配POSITION(): 子串位置查找
关于 TDengine
TDengine 专为物联网IoT平台、工业大数据平台设计。其中,TDengine TSDB 是一款高性能、分布式的时序数据库(Time Series Database),同时它还带有内建的缓存、流式计算、数据订阅等系统功能;TDengine IDMP 是一款AI原生工业数据管理平台,它通过树状层次结构建立数据目录,对数据进行标准化、情景化,并通过 AI 提供实时分析、可视化、事件管理与报警等功能。
