修剪字符串直到一个值
Trimming a string until a value
我有一列有不同大小的字符串,看起来像:
abcd, efgh, ijkl2, 2345, xyzw
我需要将它 trim 分成 2 个不同的列,并从右边获取逗号前的字符串,然后是另一个,所以我将有另外 2 个列:
2345 xyz
我试过只获取第一个逗号之前的字符串的第一部分:
RTRIM(LTRIM(RIGHT(A.[column],charindex(',',A.[column]+',')-1))) as 'aa'
RIGHT(A.[column], len(A.[column]) - charindex(',',A.[column])) as 'ab'
但是我弄混了,有时我得到逗号后面的一些值,但不完整。
有什么想法吗?
谢谢,我很感激。
如果你是 sql 服务器 2016...
,你可以使用 string_split
尝试这样的事情:
drop TABLE REC.TestTable;
CREATE TABLE REC.TestTable (id int identity, --Avoid using keywords for column names
str varchar(500));
GO
INSERT INTO REC.TestTable (str)
VALUES ('abcd, efgh, ijkl2, 123, ijk'),
('abcd, efgh, ijkl2, 4567, lmn'),
('abcd, efgh, ijkl2, 89, opqr')
;
GO
with tmp as (
select f1.*, f2.value, row_number() over(partition by id order by (select null)) position
from REC.TestTable f1 cross apply STRING_SPLIT(str, ',') f2
)
select f1.*, f2.value ValPos1, f3.value ValPos2, f4.value ValPos3, f5.value ValPos4, f6.value ValPos5
from REC.TestTable f1
left outer join tmp f2 on f1.id=f2.id and f2.position =1
left outer join tmp f3 on f1.id=f3.id and f3.position =2
left outer join tmp f4 on f1.id=f4.id and f4.position =3
left outer join tmp f5 on f1.id=f5.id and f5.position =4
left outer join tmp f6 on f1.id=f6.id and f6.position =5
SQL服务器中这样的字符串函数,真是蛋疼。我喜欢使用 apply
进行此类操作,因为这样可以更轻松地保留中间结果。
对于这个特定问题:
select v.str, v2.lastval, v3.secondlastval
from (values ('abcd, efgh, ijkl2, 2345, xyzw')) v(str) cross apply
(select stuff(str, 1, len(str) - charindex(',', reverse(str)) + 2, ''),
stuff(str, len(str) - charindex(',', reverse(str)) + 1, len(str), '')
) v2(lastval, rest) cross apply
(select stuff(v2.rest, 1, len(v2.rest) - charindex(',', reverse(v2.rest)) + 2, ''),
stuff(v2.rest, len(v2.rest) - charindex(',', reverse(v2.rest)) + 1, len(v2.rest), '')
) v3(secondlastval, rest);
话虽如此,您可能应该重新考虑您的数据结构。在分隔字符串中存储值列表在 SQL 中是一种糟糕的数据结构,因为 SQL 没有很好的字符串处理能力。相反,您应该使用 junction/association table.
我有一列有不同大小的字符串,看起来像:
abcd, efgh, ijkl2, 2345, xyzw
我需要将它 trim 分成 2 个不同的列,并从右边获取逗号前的字符串,然后是另一个,所以我将有另外 2 个列:
2345 xyz
我试过只获取第一个逗号之前的字符串的第一部分:
RTRIM(LTRIM(RIGHT(A.[column],charindex(',',A.[column]+',')-1))) as 'aa'
RIGHT(A.[column], len(A.[column]) - charindex(',',A.[column])) as 'ab'
但是我弄混了,有时我得到逗号后面的一些值,但不完整。
有什么想法吗?
谢谢,我很感激。
如果你是 sql 服务器 2016...
,你可以使用 string_split尝试这样的事情:
drop TABLE REC.TestTable;
CREATE TABLE REC.TestTable (id int identity, --Avoid using keywords for column names
str varchar(500));
GO
INSERT INTO REC.TestTable (str)
VALUES ('abcd, efgh, ijkl2, 123, ijk'),
('abcd, efgh, ijkl2, 4567, lmn'),
('abcd, efgh, ijkl2, 89, opqr')
;
GO
with tmp as (
select f1.*, f2.value, row_number() over(partition by id order by (select null)) position
from REC.TestTable f1 cross apply STRING_SPLIT(str, ',') f2
)
select f1.*, f2.value ValPos1, f3.value ValPos2, f4.value ValPos3, f5.value ValPos4, f6.value ValPos5
from REC.TestTable f1
left outer join tmp f2 on f1.id=f2.id and f2.position =1
left outer join tmp f3 on f1.id=f3.id and f3.position =2
left outer join tmp f4 on f1.id=f4.id and f4.position =3
left outer join tmp f5 on f1.id=f5.id and f5.position =4
left outer join tmp f6 on f1.id=f6.id and f6.position =5
SQL服务器中这样的字符串函数,真是蛋疼。我喜欢使用 apply
进行此类操作,因为这样可以更轻松地保留中间结果。
对于这个特定问题:
select v.str, v2.lastval, v3.secondlastval
from (values ('abcd, efgh, ijkl2, 2345, xyzw')) v(str) cross apply
(select stuff(str, 1, len(str) - charindex(',', reverse(str)) + 2, ''),
stuff(str, len(str) - charindex(',', reverse(str)) + 1, len(str), '')
) v2(lastval, rest) cross apply
(select stuff(v2.rest, 1, len(v2.rest) - charindex(',', reverse(v2.rest)) + 2, ''),
stuff(v2.rest, len(v2.rest) - charindex(',', reverse(v2.rest)) + 1, len(v2.rest), '')
) v3(secondlastval, rest);
话虽如此,您可能应该重新考虑您的数据结构。在分隔字符串中存储值列表在 SQL 中是一种糟糕的数据结构,因为 SQL 没有很好的字符串处理能力。相反,您应该使用 junction/association table.