SQL Server从字符串末尾查询2个字符之间的substr

时间:2016-04-25 03:34:02

标签: sql-server

我是sql的新手。请帮忙。

我的表格列值如下

XYZ_3244H_V65_C005_Z1234567455_P_F_20160127_0137.txt
ERTL_3244H_V65_C005_YIIUUUUUUAB_1P_W_20160316_1227.txt
WTERN_3244H_VTWT05_TWJEONSOSJS_QWT_N_20160316_0937.txt

我想要一个输出

的查询
Z1234567455
YIIUUUUUUAB
TWJEONSOSJS

我需要提取从字符串的反向计数的第4和第5个下划线之间的值。请帮忙。 TIA。

4 个答案:

答案 0 :(得分:0)

使用numbers表可以完成此任务,您只需创建数字表..

declare @string varchar(max)

set @string='_'+'XYZ_3244H_V65_C005_Z1234567455_P_F_20160127_0137.txt'+'_'


select 
substring (@string,n+1,charindex('_',@string,n+1)-n-1)
from numbers 
where 
substring(@string,n,1)='_'
and  n<len(@string)

您也可以使用rownumber在以下任何地方选择值..

select 
substring (@string,n+1,charindex('_',@string,n+1)-n-1),row_number() over (order by charindex('_',@string,n+1)) as rn
from numbers 
where 
substring(@string,n,1)='_'
and  n<len(@string)

然后使用cte在任何地方获取数字,例如

;with cte
as
(
select 
substring (@string,n+1,charindex('_',@string,n+1)-n-1) as splitstrig,row_number() over (order by charindex('_',@string,n+1)) as rn
from numbers 
where 
substring(@string,n,1)='_'
and  n<len(@string)
)
select * from cte where rn=5

答案 1 :(得分:0)

我喜欢这些东西的功能。如果格式改变,你有一个地方可以解决它。

试试这个

CREATE FUNCTION [dbo].[extract_part](@VAL varchar(max))     
returns varchar(16)
as     
begin     
    declare
        @idx int,
        @split varchar(64),
        @result varchar(16),
        @count int;
    declare 
        @tbl TABLE (id int identity(1,1), col varchar(64));

    select @idx = 1     
        if len(@VAL )<1 or @VAL is null  return null;     

    while @idx!= 0     
    begin     
        set @idx = charindex('_',@VAL)     
        if @idx!=0     
            set @split= left(@VAL,@idx - 1)     
        else     
            set @split= @VAL

        if(len(@split)>0)
            insert into @tbl(col) values(@split)     

        set @VAL= right(@VAL,len(@VAL) - @idx)     
        if len(@VAL) = 0 break     
    end

    select @count = count(1) from @tbl;

    select @result = col from @tbl where id = @count - 4;

return @result  
end

select [dbo].[extract_part]('XYZ_3244H_V65_C005_Z1234567455_P_F_20160127_0137.txt')

PS。 SQL 2016配备了一个新的SPLIT函数,可以简化这一过程。

答案 2 :(得分:0)

With use of xml:

DECLARE @xml xml

;WITH cte AS (
SELECT REVERSE(string) as string
FROM (VALUES 
('XYZ_3244H_V65_C005_Z1234567455_P_F_20160127_0137.txt'),
('ERTL_3244H_V65_C005_YIIUUUUUUAB_1P_W_20160316_1227.txt'),
('WTERN_3244H_VTWT05_TWJEONSOSJS_QWT_N_20160316_0937.txt')
) AS t(string)
)

SELECT @xml =(
SELECT CAST('<b><a>' +REPLACE(string,'_','</a><a>') + '</a></b>' as xml)
FROM cte
FOR XML PATH ('')
)

SELECT REVERSE(t.v.value('a[5]','nvarchar(20)'))
FROM @xml.nodes('/b') as t(v)

Output:

--------------------
Z1234567455
YIIUUUUUUAB
TWJEONSOSJS

(3 row(s) affected)

答案 3 :(得分:-1)

在MySQL 中,您可以这样做。

select substring_index(substring_index(val, '_', -5),'_',1) from
(select 'XYZ_3244H_V65_C005_Z1234567455_P_F_20160127_0137.txt' val) t