在SQL视图的创建过程中,经常会遇到需要对字段中的字符串进行复杂截取的需求,比如从拼接的地址中提取城市信息、从带分隔符的编码中拆分出特定部分等。SUBSTRING函数负责按指定长度截取字符串,CHARINDEX函数负责定位特定字符的位置,两者配合可以覆盖绝大多数视图内的字符串截取场景。

SUBSTRING与CHARINDEX函数基础语法
SUBSTRING函数
SUBSTRING函数用于从字符串的指定位置开始,截取指定长度的字符,基础语法如下:
-- 语法:SUBSTRING(字符串表达式, 起始位置, 截取长度)
-- 示例:从字符串第2位开始截取3个字符
SELECT SUBSTRING('abcdef', 2, 3) AS result; -- 返回bcd
CHARINDEX函数
CHARINDEX函数用于返回指定字符或子字符串在目标字符串中首次出现的位置,基础语法如下:
-- 语法:CHARINDEX(要查找的字符/子串, 目标字符串, 起始查找位置(可选))
-- 示例:查找@在字符串中的位置
SELECT CHARINDEX('@', 'test@ippipp.com') AS position; -- 返回5
视图中复杂字符串截取的常见场景
场景1:截取分隔符前的字符串
假设用户表的full_address字段存储格式为“省份-城市-区县-详细地址”,需要在视图中单独提取城市信息,即第一个横杠和第二个横杠之间的内容。
-- 创建提取城市信息的视图
CREATE VIEW user_city_view AS
SELECT
user_id,
full_address,
-- 先找到第一个-的位置,再找到第二个-的位置,计算截取长度
SUBSTRING(
full_address,
CHARINDEX('-', full_address) + 1, -- 起始位置是第一个-的后一位
CHARINDEX('-', full_address, CHARINDEX('-', full_address) + 1) - CHARINDEX('-', full_address) - 1 -- 截取长度
) AS city
FROM user_info;
场景2:截取最后一个分隔符后的字符串
如果字段中是“部门1/部门2/部门3/岗位名称”的格式,需要提取最后的岗位名称,也就是最后一个斜杠后的内容。
-- 创建提取岗位名称的视图
CREATE VIEW user_post_view AS
SELECT
user_id,
dept_post,
-- 先反转字符串找到最后一个/的位置,再计算原字符串中最后一个/的位置
SUBSTRING(
dept_post,
LEN(dept_post) - CHARINDEX('/', REVERSE(dept_post)) + 2, -- 起始位置
LEN(dept_post) -- 截取长度取剩余全部长度
) AS post_name
FROM employee_info;
场景3:处理不存在分隔符的边界情况
当目标字符串中可能不存在指定的分隔符时,需要增加判断逻辑避免函数报错,比如截取邮箱的域名部分,若邮箱格式异常则直接返回原字符串。
-- 创建提取邮箱域名的视图,处理无@的情况
CREATE VIEW user_email_domain_view AS
SELECT
user_id,
email,
CASE
WHEN CHARINDEX('@', email) > 0 THEN
SUBSTRING(email, CHARINDEX('@', email) + 1, LEN(email) - CHARINDEX('@', email))
ELSE
email
END AS email_domain
FROM user_account;
视图中字符串截取的注意事项
- SUBSTRING的起始位置参数不能小于1,若CHARINDEX返回0(未找到目标字符),需要提前做判断,否则会报错。
- 视图中使用的字符串函数会随视图查询触发执行,若数据量较大,建议先对原始字段做必要的索引优化,避免查询性能过低。
- 不同数据库对字符串函数的支持略有差异,比如MySQL中定位字符使用
INSTR函数,若跨数据库使用需要调整函数写法。 - 若截取逻辑较为复杂,建议先在单独的查询中验证截取结果,确认无误后再写入视图定义中,减少调试成本。