根据文本值和数值(例如 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 避免重复计算的一种奇特方式。