根据文本值和数值(例如 patindex)拆分列中的字符串
Split strings in a column based on text values and numerical values such as patindex
我有一列显示股票市场期权数据,如下所示:
GME240119C00020000
QQQ240119C00305000
NFLX240119P00455000
我希望能够将它们拆分成这样:
GME|240119|C|00020000
QQQ|240119|C|00305000
NFLX|240119|P|00455000
我可以使用下面的代码将第一部分与代码名称分开,但我不知道如何分开其余的字符串。
case patindex('%[0-9]%', str)
when 0 then str
else left(str, patindex('%[0-9]%', str) -1 )
end
from t
编辑:对于任何想知道的人,我使用了下面 Dale 的解决方案来获得我想要的结果。我编辑了他提供的查询,使各个部分显示为单独的列
select
substring(T.contractSymbol,1,C1.Position-1) as a
,substring(T.contractSymbol,C1.Position,6) as b
,substring(S1.Part,1,1) as c
,substring(S1.Part,2,len(S1.Part)) as d
from Options_Data_All T
cross apply (
values (patindex('%[0-9]%', T.contractSymbol))
) C1 (Position)
cross apply (
values (substring(contractSymbol, C1.Position+6, len(T.contractSymbol)))
) S1 (Part);
继续做您使用 SUBSTRING
开始做的事情。因此,正如您确实找到了第一个数字,实际上在您的情况下,根据提供的数据,其他所有内容都是固定长度的,因此您不必再搜索,只需拆分字符串即可。
declare @Test table (Contents nvarchar(max));
insert into @Test (Contents)
values
('GME240119C00020000'),
('QQQ240119C00305000'),
('NFLX240119P00455000');
select
substring(T.Contents,1,C1.Position-1) + '|' + substring(T.Contents,C1.Position,6) + '|' + substring(S1.Part,1,1) + '|' + substring(S1.Part,2,len(S1.Part))
from @Test T
cross apply (
values (patindex('%[0-9]%', T.Contents))
) C1 (Position)
cross apply (
values (substring(Contents, C1.Position+6, len(T.Contents)))
) S1 (Part);
Returns:
Data
GME|240119|C|00020000
QQQ|240119|C|00305000
NFLX|240119|P|00455000
如果可以假设除第一列以外的所有列都是固定宽度,那么一个简单的 SUBSTRING
解决方案就足够了,例如
select
substring(Contents,1,len(Contents)-15)
+ '|' + substring(Contents,len(Contents)-14,6)
+ '|' + substring(Contents,len(Contents)-8,1)
+ '|' + substring(Contents,len(Contents)-7,8) [Data]
from @Test;
注意:CROSS APPLY
只是使用 sub-query 避免重复计算的一种奇特方式。
我有一列显示股票市场期权数据,如下所示:
GME240119C00020000
QQQ240119C00305000
NFLX240119P00455000
我希望能够将它们拆分成这样:
GME|240119|C|00020000
QQQ|240119|C|00305000
NFLX|240119|P|00455000
我可以使用下面的代码将第一部分与代码名称分开,但我不知道如何分开其余的字符串。
case patindex('%[0-9]%', str)
when 0 then str
else left(str, patindex('%[0-9]%', str) -1 )
end
from t
编辑:对于任何想知道的人,我使用了下面 Dale 的解决方案来获得我想要的结果。我编辑了他提供的查询,使各个部分显示为单独的列
select
substring(T.contractSymbol,1,C1.Position-1) as a
,substring(T.contractSymbol,C1.Position,6) as b
,substring(S1.Part,1,1) as c
,substring(S1.Part,2,len(S1.Part)) as d
from Options_Data_All T
cross apply (
values (patindex('%[0-9]%', T.contractSymbol))
) C1 (Position)
cross apply (
values (substring(contractSymbol, C1.Position+6, len(T.contractSymbol)))
) S1 (Part);
继续做您使用 SUBSTRING
开始做的事情。因此,正如您确实找到了第一个数字,实际上在您的情况下,根据提供的数据,其他所有内容都是固定长度的,因此您不必再搜索,只需拆分字符串即可。
declare @Test table (Contents nvarchar(max));
insert into @Test (Contents)
values
('GME240119C00020000'),
('QQQ240119C00305000'),
('NFLX240119P00455000');
select
substring(T.Contents,1,C1.Position-1) + '|' + substring(T.Contents,C1.Position,6) + '|' + substring(S1.Part,1,1) + '|' + substring(S1.Part,2,len(S1.Part))
from @Test T
cross apply (
values (patindex('%[0-9]%', T.Contents))
) C1 (Position)
cross apply (
values (substring(Contents, C1.Position+6, len(T.Contents)))
) S1 (Part);
Returns:
Data |
---|
GME|240119|C|00020000 |
QQQ|240119|C|00305000 |
NFLX|240119|P|00455000 |
如果可以假设除第一列以外的所有列都是固定宽度,那么一个简单的 SUBSTRING
解决方案就足够了,例如
select
substring(Contents,1,len(Contents)-15)
+ '|' + substring(Contents,len(Contents)-14,6)
+ '|' + substring(Contents,len(Contents)-8,1)
+ '|' + substring(Contents,len(Contents)-7,8) [Data]
from @Test;
注意:CROSS APPLY
只是使用 sub-query 避免重复计算的一种奇特方式。