Get the character between first 2 special character in SQL

前端 未结 2 1832
你的背包
你的背包 2020-11-30 14:51

I have data in sql (Just to note: SQL STudio is the IDE) like:

data
a_10_b_c
a_1_b_c

I want to get t

2条回答
  •  囚心锁ツ
    2020-11-30 15:03

    This would be my approach:

    SELECT CAST('' + REPLACE(data,'_','') + '' AS XML).value('/x[2]','int')
    FROM YourTable
    

    First you transform this to an XML and then you pick the second node..

    EDIT: Some more examples where this approach is usefull:

    CROSS APPLY: You can use this approach to get several tokens at once

    DECLARE @tbl TABLE(separated VARCHAR(100));
    INSERT INTO @tbl VALUES('1_23:50_Look_this_is_a_test'),('2_12:00_that''s_one_more_test'),('3_13:30_great!_It_works!');
    
    SELECT Converted.value('/x[1]','int') AS number
          ,Converted.value('/x[2]','time') AS time
          ,Converted.value('/x[3]','varchar(max)') AS text
    FROM @tbl
    CROSS APPLY(SELECT CAST('' + REPLACE(separated,'_','') + '' AS XML) AS Converted) AS MySeparated
    --type-safe and easy:
    /*
    number  time    text
    1       23:50   Look
    2       12:00   that's
    3       13:30   great!
    */
    GO
    

    CTE: use as parameter

    DECLARE @Parameter VARCHAR(100)='1_12:30_SomeValue';
    WITH MyParameters AS
    (
        SELECT CAST('' + REPLACE(@Parameter,'_','') + '' AS XML).value('/x[1]','int') AS IntParam
              ,CAST('' + REPLACE(@Parameter,'_','') + '' AS XML).value('/x[2]','time') AS TimeParam
              ,CAST('' + REPLACE(@Parameter,'_','') + '' AS XML).value('/x[3]','varchar(max)') AS TextParam
    )
    SELECT IntParam,TimeParam,TextParam
    FROM MyParameters
    /*
    IntParam    TimeParam   TextParam
    1           12:30:00    SomeValue
    */
    GO
    

    Split String: Transform to list

    DECLARE @MyIDs VARCHAR(100)='3,5,7';
    SELECT A.B.value('.','int') TheIntValue
    FROM(SELECT CAST('' + REPLACE(@MyIDs,',','') + '' AS XML) AS MyListAsXML) AS x
    CROSS APPLY MyListAsXML.nodes('/x') AS A(B)
    
    /*
    TheIntValue
    3
    5
    7
    */
    GO
    

    Dynamic IN Statement

    DECLARE @tbl TABLE(ID INT,Content VARCHAR(max));
    INSERT INTO @tbl VALUES(1,'Value 1'),(2,'Value 2'),(3,'Value 3'),(4,'Value 4'),(5,'Value 5'),(6,'Value 6'),(7,'Value 7');
    
    DECLARE @MyIDs VARCHAR(100)='3,5,7';
    /*
    This won't work (due to the fact, that @MyIDs is not a list of INTs but a text
    SELECT * FROM @tbl WHERE ID IN(@MyIDs)
    */
    WITH AsList AS
    (
        SELECT A.B.value('.','int') TheIntValue
        FROM(SELECT CAST('' + REPLACE(@MyIDs,',','') + '' AS XML) AS MyListAsXML) AS x
        CROSS APPLY MyListAsXML.nodes('/x') AS A(B)
    
    )
    SELECT * FROM @tbl WHERE ID IN(SELECT TheIntValue FROM AsList)
    
    /*
    ID  Content
    3   Value 3
    5   Value 5
    7   Value 7
    */
    

提交回复
热议问题