TSQL - 带有“.”的字符串的一部分字符

TSQL - part of string with '.' char

我有字符串,可以是:

1.A.1  
1.1.A.1  

我需要 SELECT 其中 return 我:

1. as 1stLevel, 1.A. as 2ndLevel
1. as 1stLevel, 1.1. as 2ndLevel, 1.1.A. as 3rdLevel

现在我用子串来解决这个问题,但是当到 10 时有问题,例如:

11.D.12.

您可以将字符串转换为 xml 并使用路径。如果您确定字符串的长度,则可以使用 table 值函数或子字符串。

Xpath 示例:

if object_id('tempdb..#tmp_xmldata') is not null drop table #tmp_xmldata
select cast('<a>' + replace(input.string, '.', '</a><a>') + '</a>' as xml) as XmlData
into #tmp_xmldata
from (
   select '1.A.1' as string
   union all
   select '1.1.A.1') as input

select
   *,
   XmlData.value('/a[1]', 'varchar(max)') as [1rdLevel],
   XmlData.value('/a[2]', 'varchar(max)') as [2rdLevel],
   XmlData.value('/a[3]', 'varchar(max)') as [3rdLevel],
   XmlData.value('/a[4]', 'varchar(max)') as [4rdLevel]
from #tmp_xmldata as x

子字符串:

select
   string,
   substring(string, 1, 1),
   substring(string, 3, 1),
   substring(string, 5, 1),
   substring(string, 7, 1),
   substring(string, 9, 1)
from (
   select '1.A.1' as string
   union all
   select '1.1.A.1') as input

或者你可以滥用 parsename 函数:

select
   string,
   parsename(string, 1),
   parsename(string, 2),
   parsename(string, 3),
   parsename(string, 4)
from (
   select '1.A.1' as string
   union all
   select '1.1.A.1') as input

我不能推荐子字符串,因为您可能对非 onechar 字符串有疑问。最好的解决方案是 parsename 函数,因为它非常简单。 parsename 的限制是 4 个级别。

我们可以通过创建用户定义的函数来使其更加动态。 Wwe 可以在 STRING_SPLIT 函数的帮助下拆分字符串。

用户自定义函数

create function [dbo].[fn_level](@level varchar(100))
returns varchar(max)
as begin
    declare @retLevel as varchar(max);
    declare @t as table([rn] int identity(1, 1), [val] varchar(100));
    insert into @t([val])
    select [value] from string_split(@level, '.');
    select @retLevel = stuff((
            select ', ' + [val] + ' as Level' + cast([rn] as varchar(10))
            from @t
            for xml path('')
        )
        , 1, 2, ''
    );  
    return @retLevel;
end

免责声明:STRING_SPLIT 函数可用于 SQL Server 2016+

Fiddle demo