Oracle SQL:仅当字符串存在第4和第5个令牌时,提取并拼接以点分隔的最后两个令牌
我来帮你搞定这个需求!根据你的描述,我们需要从code_table表的code列里,筛选出刚好包含5个以点分隔的令牌的字符串(毕竟要同时有第4和第5个令牌,且最多5个,那就是刚好5个啦),然后把最后两个令牌直接拼起来生成新代码。下面分不同数据库给你具体的实现方法:
实现方案
核心逻辑梳理
- 仅处理令牌数量为5的
code字符串(满足同时存在第4、第5个令牌,且令牌数不超过5的要求) - 提取第4和第5个令牌,直接拼接成新代码
MySQL 实现
在MySQL里,我们可以借助SUBSTRING_INDEX分割字符串,结合LENGTH和REPLACE判断令牌数量:
SELECT code, CONCAT( SUBSTRING_INDEX(SUBSTRING_INDEX(code, '.', 4), '.', -1), SUBSTRING_INDEX(code, '.', -1) ) AS new_code FROM code_table WHERE LENGTH(code) - LENGTH(REPLACE(code, '.', '')) = 4; -- 4个点对应5个令牌
简单解释下:
LENGTH(code) - LENGTH(REPLACE(code, '.', '')) = 4:统计字符串中点的数量,4个点意味着刚好是5个令牌SUBSTRING_INDEX(SUBSTRING_INDEX(code, '.', 4), '.', -1):精准提取第4个令牌SUBSTRING_INDEX(code, '.', -1):直接提取最后一个(第5个)令牌CONCAT函数把两个令牌拼接成最终的new_code
PostgreSQL 实现
PostgreSQL可以用STRING_TO_ARRAY把字符串转成数组,操作起来更直观:
SELECT code, (code_array[4] || code_array[5]) AS new_code FROM ( SELECT code, STRING_TO_ARRAY(code, '.') AS code_array FROM code_table ) t WHERE array_length(code_array, 1) = 5;
关键逻辑:
STRING_TO_ARRAY(code, '.'):把code按点分割成数组,PostgreSQL数组索引从1开始array_length(code_array, 1) = 5:筛选出刚好包含5个令牌的记录code_array[4] || code_array[5]:直接拼接第4、第5个数组元素得到新代码
SQL Server 实现
SQL Server可以用STRING_SPLIT结合行号来定位目标令牌:
WITH split_codes AS ( SELECT ct.code, s.value AS token, ROW_NUMBER() OVER (PARTITION BY ct.code ORDER BY (SELECT NULL)) AS token_num FROM code_table ct CROSS APPLY STRING_SPLIT(ct.code, '.') s ) SELECT sc.code, CONCAT(sc4.token, sc5.token) AS new_code FROM split_codes sc4 JOIN split_codes sc5 ON sc4.code = sc5.code AND sc4.token_num = 4 AND sc5.token_num = 5 WHERE (SELECT COUNT(*) FROM split_codes sc WHERE sc.code = sc4.code) = 5;
步骤说明:
- 先用CTE
split_codes把每个code分割成令牌,并给每个令牌按顺序编号 - 通过自连接找到每个
code对应的第4、第5个令牌,同时筛选出令牌总数为5的记录 - 用
CONCAT拼接两个令牌得到新代码
如果需要把结果更新回原表(假设表已有new_code列),以MySQL为例可以这么写:
UPDATE code_table SET new_code = CONCAT( SUBSTRING_INDEX(SUBSTRING_INDEX(code, '.', 4), '.', -1), SUBSTRING_INDEX(code, '.', -1) ) WHERE LENGTH(code) - LENGTH(REPLACE(code, '.', '')) = 4;
如果没有new_code列,先执行ALTER TABLE code_table ADD COLUMN new_code VARCHAR(255);(根据实际需求调整字段类型和长度)即可。
内容的提问来源于stack exchange,提问作者prain99
相关产品推荐
相关产品推荐

