2016-04-25 105 views
0

我是新来的sql。请帮忙。SQL Server查询到substr从字符串末尾开始的2个字符

我与列值的表如下

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 

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

+0

可能重复http://stackoverflow.com/questions/2647/how-do-i-split-a-string -so-i-can-access-item-x –

+0

那么,有没有任何答案对你有帮助? – gofr1

回答

-1

在MySQL中,你可以这样做。

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

MySql <> SQL Server – Gregg

+0

@Gregg - 我知道。我想发布我知道的东西。我的系统上没有安装MS SQL。否则,我会。 :) – MontyPython

+0

这就是为什么我用粗体标记它。 – MontyPython

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 
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功能,可以简化这一点。

0

随着使用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) 

输出:的

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

(3 row(s) affected)