Sql server 下划线之间的子字符串-SQL Server 2008

Sql server 下划线之间的子字符串-SQL Server 2008,sql-server,substring,Sql Server,Substring,我的SQL Server 2008中存储了一个字符串,我想提取下划线之间的值。我有一个工作代码,但当字符串的长度改变时会产生问题。你能告诉我一个更好的方法吗 示例字符串为 'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US' 我想提取 '1234567' 它将始终位于最后一个下划线的第二个和第三个之间 我正在使用以下代码: substring(right(sample_table.file_name, 21), 1, 7) 其中,sample

我的SQL Server 2008中存储了一个字符串,我想提取下划线之间的值。我有一个工作代码,但当字符串的长度改变时会产生问题。你能告诉我一个更好的方法吗

示例字符串为

'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US' 
我想提取

'1234567'
它将始终位于最后一个下划线的第二个和第三个之间

我正在使用以下代码:

substring(right(sample_table.file_name, 21), 1, 7)
其中,sample_table是表名,file_name是列名


假设您想要第三个位置,可能是一点XML,那么输出应该是1234567

范例


假设您想要第三个位置,可能需要一点XML

范例


好的,这里有一个同样适用于SQLServer2008的解决方案

首先创建一个函数:

创建函数dbo。StringSplit@stringnvarcharMAX,@separator nvarcharMAX 返回 @列表表[index]int[value]nvarcharMAX 像 开始 声明@value NVARCHARmax 声明@pos INT 声明@index INT 设置@index=1 虽然CHARINDEX@separator,@string>0 开始 选择@pos=CHARINDEX@separator,@string 选择@value=SUBSTRING@string,1,@pos-1 插入@list选择@index,@value 选择@string=SUBSTRING@string,@pos+LEN@separator, LEN@string-@pos 设置@index=@index+1 终止 插入@list 选择@index,@string 回来 终止 然后拆分这些值并选择正确的值

选择* 来自dbo.StringSplit'AAAA_bbbbbbusemail000000001_1234567_Normal_ABC_US','u' 其中[索引]=3 返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US

好的,这里有一个同样适用于SQLServer2008的解决方案

首先创建一个函数:

创建函数dbo。StringSplit@stringnvarcharMAX,@separator nvarcharMAX 返回 @列表表[index]int[value]nvarcharMAX 像 开始 声明@value NVARCHARmax 声明@pos INT 声明@index INT 设置@index=1 虽然CHARINDEX@separator,@string>0 开始 选择@pos=CHARINDEX@separator,@string 选择@value=SUBSTRING@string,1,@pos-1 插入@list选择@index,@value 选择@string=SUBSTRING@string,@pos+LEN@separator, LEN@string-@pos 设置@index=@index+1 终止 插入@list 选择@index,@string 回来 终止 然后拆分这些值并选择正确的值

选择* 来自dbo.StringSplit'AAAA_bbbbbbusemail000000001_1234567_Normal_ABC_US','u' 其中[索引]=3 返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US

一种方法是使用类似DelimitedSplit8K函数的字符串拆分器。如果您想要的只是第三个值,那么下面是一个如何实现它的示例

CREATE TABLE #TableA (ID Int, DelimitedString Varchar(100));

INSERT #TableA(ID, DelimitedString)VALUES(1, 'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US'), (2, 'ZZZZ_YYYYUSEmail000000002_9876543_Abnormal_XYZ_US');

SELECT
    a.ID,
    split.Item AS ThirdValue
FROM
    #TableA a
CROSS APPLY
    master.dbo.DelimitedSplit8K(a.DelimitedString, '_') split
WHERE
    split.ItemNumber = 3

DROP TABLE #TableA;
返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US
如果您希望从字符串中获得更多值,那么该方法可以与PIVOT结合使用,假设存在静态数量的值,以便将值列表转换为列以便于使用。下面是一个使用PIVOT的示例

CREATE TABLE #TableA (ID Int, DelimitedString Varchar(100));

INSERT
    #TableA(ID, DelimitedString)
VALUES
    (1, 'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US'),
    (2, 'ZZZZ_YYYYUSEmail000000002_9876543_Abnormal_XYZ_US');

SELECT
    pvt.ID,
    pvt.[1] AS FirstValue,
    pvt.[2] AS SecondValue,
    pvt.[3] AS ThirdValue,
    pvt.[4] AS FourthValue,
    pvt.[5] AS FifthValue,
    pvt.[6] AS SixthValue
FROM
    (
    SELECT
        a.ID,
        a.DelimitedString,
        split.ItemNumber,
        split.Item
    FROM
        #TableA a
    CROSS APPLY master.dbo.DelimitedSplit8K(a.DelimitedString, '_') split
    ) list
PIVOT(MAX(Item)
FOR ItemNumber IN([1], [2], [3], [4], [5], [6])
    ) pvt;

DROP TABLE #TableA;
返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US

一种方法是使用类似DelimitedSplit8K函数的字符串拆分器。如果您想要的只是第三个值,那么下面是一个如何实现它的示例

CREATE TABLE #TableA (ID Int, DelimitedString Varchar(100));

INSERT #TableA(ID, DelimitedString)VALUES(1, 'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US'), (2, 'ZZZZ_YYYYUSEmail000000002_9876543_Abnormal_XYZ_US');

SELECT
    a.ID,
    split.Item AS ThirdValue
FROM
    #TableA a
CROSS APPLY
    master.dbo.DelimitedSplit8K(a.DelimitedString, '_') split
WHERE
    split.ItemNumber = 3

DROP TABLE #TableA;
返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US
如果您希望从字符串中获得更多值,那么该方法可以与PIVOT结合使用,假设存在静态数量的值,以便将值列表转换为列以便于使用。下面是一个使用PIVOT的示例

CREATE TABLE #TableA (ID Int, DelimitedString Varchar(100));

INSERT
    #TableA(ID, DelimitedString)
VALUES
    (1, 'AAAA_BBBBUSEmail000000001_1234567_Normal_ABC_US'),
    (2, 'ZZZZ_YYYYUSEmail000000002_9876543_Abnormal_XYZ_US');

SELECT
    pvt.ID,
    pvt.[1] AS FirstValue,
    pvt.[2] AS SecondValue,
    pvt.[3] AS ThirdValue,
    pvt.[4] AS FourthValue,
    pvt.[5] AS FifthValue,
    pvt.[6] AS SixthValue
FROM
    (
    SELECT
        a.ID,
        a.DelimitedString,
        split.ItemNumber,
        split.Item
    FROM
        #TableA a
    CROSS APPLY master.dbo.DelimitedSplit8K(a.DelimitedString, '_') split
    ) list
PIVOT(MAX(Item)
FOR ItemNumber IN([1], [2], [3], [4], [5], [6])
    ) pvt;

DROP TABLE #TableA;
返回

index       value
----------- ---------
3           1234567
ID  ThirdValue
--  ----------
1   1234567
2   9876543
ID  FirstValue  SecondValue           ThirdValue  FourthValue  FifthValue  SixthValue
--  ----------  --------------------  ----------  -----------  ----------  ----------
1   AAAA        BBBBUSEmail000000001  1234567     Normal       ABC         US
2   ZZZZ        YYYYUSEmail000000002  9876543     Abnormal     XYZ         US

谢谢这同样有效,但我将采用@JohnThanks共享的方法。这也行得通,但我还是要用@JohnJust分享的方法作为说明:SQLServer2008和2008R2现在已经没有扩展支持了--该升级了!请注意:SQLServer2008和2008R2现在已经没有扩展支持了--该升级了@PrayasBhatnagar接受另一个答案很好。说真的,我对此没有异议,但你究竟为什么要接受循环解析/拆分函数呢。我感到震惊的是,当有基于集合的备选方案可用时,人们仍在发布这些内容。为了您的技术发展,请仔细查看Kenny链接的功能。尊敬的约翰,我确实看过肯尼的答案,但还没有试过。不确定它是否符合我的要求。你和皮埃尔的回答支持了我的要求,因此接受了答案。我理解你所说的,并且已经很好地理解了,但我没有否定皮埃尔的答案,也没有接受肯尼的答案的唯一原因是因为一个支持我的要求,而另一个更好的解决方案还没有经过测试。就这样。Peace@PrayasBhatnagar几年前,我有一个类似的循环函数。当我转向基于集合的方法时,我对性能的提高感到惊讶。高性能的功能是一个很好的促成因素。努夫说@PrayasBhatnagar接受另一个答案很好。说真的,我对此没有异议,但你究竟为什么要接受循环解析/拆分呢
不客气。我感到震惊的是,当有基于集合的备选方案可用时,人们仍在发布这些内容。为了您的技术发展,请仔细查看Kenny链接的功能。尊敬的约翰,我确实看过肯尼的答案,但还没有试过。不确定它是否符合我的要求。你和皮埃尔的回答支持了我的要求,因此接受了答案。我理解你所说的,并且已经很好地理解了,但我没有否定皮埃尔的答案,也没有接受肯尼的答案的唯一原因是因为一个支持我的要求,而另一个更好的解决方案还没有经过测试。就这样。Peace@PrayasBhatnagar几年前,我有一个类似的循环函数。当我转向基于集合的方法时,我对性能的提高感到惊讶。高性能的功能是一个很好的促成因素。努夫说