如何在给定字符串的下划线旁边获取第一个字符

时间:2018-01-19 10:58:57

标签: sql sql-server tsql

输入: 字符串

'abc_def_ghk_lmn'

输出:

dgl

7 个答案:

答案 0 :(得分:2)

你可以尝试这个(甚至创建一个函数):

 DECLARE @str varchar(250) = 'abc_def_ghk_lmn'
DECLARE @result varchar(250)='';

WHILE(charindex('_',@str)!=0)
BEGIN
    DECLARE @position int = charindex('_',@str)
    SET @result += substring(@str,@position+1,1)
    SET @str = substring(@str,@position+1,len(@str))
END

SELECT @result

答案 1 :(得分:2)

您可以使用递归CTE:

IF OBJECT_ID('tempdb..#t') is not null drop table #t
SELECT * into #t from (values (N'abc_def_ghk_lmn'), (N'a_f_k_n'), (null), ('____'), ('asasas'), ('a_sasas'), ('asas_')) T(val);

;WITH CTE AS
(
    SELECT  
         Cast(SUBSTRING(T.val, CHARINDEX('_',T.val,1) + 1, 1) as nvarchar(4000)) FC
        ,CHARINDEX('_', T.val, 1) CI 
        ,val
        ,0 [level]
    from #t T
    where CHARINDEX('_', T.val, 1) > 0
    union all 
    SELECT  
        Cast(T.FC + SUBSTRING(T.val, CHARINDEX('_',T.val,T.CI+1) + 1, 1) as nvarchar(4000)) FC
        ,CHARINDEX('_', T.val, T.CI+1) CI 
        ,val
        ,t.[level] + 1
    from CTE T
    where CHARINDEX('_',T.val,T.CI+1) > 0
)
, Res AS
(
    SELECT 
        * 
        ,ROW_NUMBER() OVER (Partition by val order by [level] desc) RN
    from CTE
)
SELECT * from Res where RN = 1

答案 2 :(得分:1)

这使用了Jeff Moden的DelimitedSplit8K功能。首先,因为我不知道您正在使用的SQL Server版本,其次,内置函数STRING_SPLIT(在SQL Server 2016及更高版本中可用)不包含项目编号值(因此如何是否会排除第一个结果?):

SELECT (SELECT LEFT(Item, 1) 
        FROM DelimitedSplit8K ('abc_def_ghk_lmn','_') DS
        WHERE DS.ItemNumber > 1
        FOR XML PATH(''));

编辑: 数据集示例:

WITH VTE AS(
    SELECT *
    FROM (VALUES ('asdgsad_sdfh_sadfh'),('_ashdf+ashd'),('jsda_sdkhfsdjf_654_asdfkhasd_567465413_kasbgdjkasdj')) V(S))
SELECT (SELECT LEFT(Item, 1) 
        FROM DelimitedSplit8K (S,'_') DS
        WHERE DS.ItemNumber > 1
        FOR XML PATH('')) AS FirstCharacters
FROM VTE;

答案 3 :(得分:0)

请尝试此-...始终使用基于SET的方法

解决方案

DECLARE @x AS XML=''
DECLARE @ AS VARCHAR(1000) = 'abc_def_ghk_lmn_'
SET @x = CAST('<A>'+ REPLACE(@,'_','</A><A>')+ '</A>' AS XML)
;WITH CTE AS
(
    SELECT t.value('.', 'VARCHAR(10)') Value FROM @x.nodes('/A') AS x(t)      
)
,CTE1 AS 
(
    SELECT * , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) rnk FROM CTE
)
,CTE2 AS
(
    SELECT SUBSTRING(Value,1,1) v , rnk FROM CTE1
)
SELECT CASE WHEN LEFT(@,1) <> '_' THEN MAX(SUBSTRING(u,2,LEN(u))) ELSE MAX(u) END finalstr from (
SELECT  
        (
            SELECT '' + v  
            FROM CTE2 a               
            FOR XML PATH('') 
        )u
FROM CTE2 )x

<强>输出

finalstr
---------------
dgl

(1 row affected) 

答案 4 :(得分:0)

试试这个:

DECLARE @String VARCHAR(50)= 'abc_def_ghk_lmn',@Result VARCHAR(10)=''

WHILE CHARINDEX('_',@String)>0
BEGIN
    SELECT @Result=@Result + SUBSTRING(@String,CHARINDEX('_',@String)+1,1)

    SELECT @String=RIGHT(@String,LEN(@String)- CHARINDEX('_',@String))
END

SELECT @Result FinalResult

<强>输出:

FinalResult
dgl

答案 5 :(得分:0)

请尝试以下

DECLARE @str TAble(String varchar(250)) 
INSERT INTO @str
SELECT 'abc_def_ghk_lmn_opq_rst_uvw_xyz'

SELECT STUFF((SELECT ''+LEFT(String,1) FROM 
(
SELECT Split.a.value('.','Varchar(1000)') As String,
 ROW_NUMBER()OVER(ORDER BY (SELECT 1)) AS Id FROM
(
SELECT CASt('<S>'+REPLACE(String,'_','</S><S>')+'</S>' AS XML )AS String
FROM @str
)as A
CROSS APPLY String.nodes ('S') AS Split(a)
)dt
WHERE dt.Id <>1
FOR XML PATH ('')),1,0,'') AS  ExpectedColumn 

结果

ExpectedColumn
--------------
dglorux

答案 6 :(得分:-1)

使用LEFT获取左侧部分,使用INSTR查找下划线,最后获取字符串:

SELECT LEFT(FIELD_1, CHARINDEX('_', FIELD_1) - 2) AS [ANY_ALIAS]
FROM TABLE_1;

编辑:现在是MSSQL ......; D