/*
有时候我们需要将如下字符串进行分割
'1,12,123'
希望得到这样的结果:
1
12
123
这里借助master.dbo.spt_values表来实现!
*/
--准备数据
IF OBJECT_ID('tempdb..#a') IS NOT NULL DROP TABLE #a
SELECT '1,12,123' AS ids INTO #a
--截取一个字符串需要知道开始位置和截取长度
--1.寻找截取的开始位置
/*
很明显对于这个字符串的开始截取位置是1(从第一个字符开始截取),那么尝试从位置1开始截取,每次截取1个字符
使用SUBSTRING(a.ids,b.number,1)后可以看到字符串的每个字符都被截取成单个的字符(一共8个字符)
但是要截取两位,三位的字符就得计算截取长度了
*/
--2.计算截取的长度
/*
分别截取1,12,123这三个数字
1,12,123
SUBSTRING(ids,1,1)----1
SUBSTRING(ids,3,2)----12
SUBSTRING(ids,6,3)----123
两个问题:1.怎么获取开始截取位置?
2.怎么计算截取长度?
解决第一个问题,可以通过加一个条件来筛选b.number,我们只需要1,3,6的值
再看看这个字符串'1,12,123' 逗号所在的位置为:2,5
试试在字符串'1,12,123' 前面加个逗号 ',1,12,123' 这时逗号的位置是:1,3,6
ok开始位置就拿到了,加个条件实现:AND SUBSTRING(','+a.ids,b.number,1)=','
看看效果:
ids number
-------- -----------
1,12,123 1
1,12,123 3
1,12,123 6
解决第二个问题:我们知道截取长度分别是1,2,3 怎么计算?
我们再来看看每个逗号的位置,以及number的数值
ids number 逗号位置
-------- ----------- -----------
1,12,123 1 2
1,12,123 3 5
1,12,123 6 0
发现逗号位置减去number将得到结果:1,2,-6
还差一点,如果逗号位置的最后一个数值是9就好了,怎么办?
试试往后再加一个逗号看看:'1,12,123,'现在最后一个逗号的位置就是9了吧!
逗号位置:CHARINDEX(',',a.ids+',',b.number)
截取长度:CHARINDEX(',',a.ids+',',b.number)-b.number
这样我们就可以计算截取长度了:
ids number 逗号位置 截取长度
-------- ----------- ----------- -----------
1,12,123 1 2 1
1,12,123 3 5 2
1,12,123 6 9 3
截取的时候,从number开始,按截取长度来截取将是:
ids number
-------- ----------- --------
1,12,123 1 1
1,12,123 3 12
1,12,123 6 123
*/
GO
SELECT a.*,b.number,
SUBSTRING(a.ids,b.number,
CHARINDEX(',',a.ids+',',b.number)-b.number
)
FROM #a a,spt_values b
WHERE b.type='P'
AND b.number BETWEEN 1 and LEN(a.ids)
AND SUBSTRING(','+a.ids,b.number,1)=','
sql 截取
最新推荐文章于 2025-02-15 20:13:47 发布