programing

SQL Server - 문자열에서 n번째 항목 찾기

mailnote 2023. 6. 20. 21:46
반응형

SQL Server - 문자열에서 n번째 항목 찾기

다음과 같은 값이 포함된 테이블 열이 있습니다.abc_1_2_3_4.gif또는zzz_12_3_3_45.gif기타.

의 값에서 각 밑줄의 인덱스를 찾고 싶습니다.4개의 밑줄만 있을 수 있지만 문자열의 모든 위치에 있을 수 있다는 점을 고려할 때 어떻게 이를 달성할 수 있습니까?

서브스트링charindex 기능을 시도해봤지만 첫번째 것만 안정적으로 잡을 수 있습니다.아이디어 있어요?

위치에 대해 내부에서 동일한 기능을 사용할 수 있습니다.+1

charindex('_', [TEXT], (charindex('_', [TEXT], 1))+1)

어디서+1찾을 시간은 다음입니다.

단방향(2k8);

select 'abc_1_2_3_4.gif  ' as img into #T
insert #T values ('zzz_12_3_3_45.gif')

;with T as (
    select 0 as row, charindex('_', img) pos, img from #T
    union all
    select pos + 1, charindex('_', img, pos + 1), img
    from T
    where pos > 0
)
select 
    img, pos 
from T 
where pos > 0   
order by img, pos

>>>>

img                 pos
abc_1_2_3_4.gif     4
abc_1_2_3_4.gif     6
abc_1_2_3_4.gif     8
abc_1_2_3_4.gif     10
zzz_12_3_3_45.gif   4
zzz_12_3_3_45.gif   7
zzz_12_3_3_45.gif   9
zzz_12_3_3_45.gif   11

갱신하다

;with T(img, starts, pos) as (
    select img, 1, charindex('_', img) from #t
    union all
    select img, pos + 1, charindex('_', img, pos + 1)
    from t
    where pos > 0
)
select 
    *, substring(img, starts, case when pos > 0 then pos - starts else len(img) end) token
from T
order by img, starts

>>>

img                 starts  pos     token
abc_1_2_3_4.gif     1       4       abc
abc_1_2_3_4.gif     5       6       1
abc_1_2_3_4.gif     7       8       2
abc_1_2_3_4.gif     9       10      3
abc_1_2_3_4.gif     11      0       4.gif  
zzz_12_3_3_45.gif   1       4       zzz
zzz_12_3_3_45.gif   5       7       12
zzz_12_3_3_45.gif   8       9       3
zzz_12_3_3_45.gif   10      11      3
zzz_12_3_3_45.gif   12      0       45.gif

사용할 수 있습니다.CHARINDEX시작 위치를 지정합니다.

DECLARE @x VARCHAR(32) = 'MS-SQL-Server';

SELECT 
  STUFF(STUFF(@x,3 , 0, '/'), 8, 0, '/') InsertString
  ,CHARINDEX('-',LTRIM(RTRIM(@x))) FirstIndexOf
  ,CHARINDEX('-',LTRIM(RTRIM(@x)), (CHARINDEX('-', LTRIM(RTRIM(@x)) )+1)) SecondIndexOf
  ,CHARINDEX('-',@x,CHARINDEX('-',@x, (CHARINDEX('-',@x)+1))+1) ThirdIndexOf
  ,CHARINDEX('-',REVERSE(LTRIM(RTRIM(@x)))) LastIndexOf;
GO
DECLARE @str AS VARCHAR(100)
SET @str='1,2  , 3,   4,   5,6'
SELECT COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[1]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[2]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[3]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[4]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[5]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[6]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[7]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[8]', 'varchar(128)')), ''),
       COALESCE(LTRIM(CAST(('<X>'+REPLACE(@str,',' ,'</X><X>')+'</X>') AS XML).value('(/X)[9]', 'varchar(128)')), '')

다음을 사용할 수 있습니다.function로.split the valuesa에 의하여delimiter그것은return a table그리고 n번째 발생을 찾으려면 그냥 a를 만드세요.select좋아요! 아니면 조금만 바꿔주세요.return당신이 필요로 하는 것 대신에.table.

CREATE FUNCTION dbo.Split
(
    @RowData nvarchar(2000),
    @SplitOn nvarchar(5)
)  
RETURNS @RtnValue table 
(
    Id int identity(1,1),
    Data nvarchar(100)
) 
AS  
BEGIN 
    Declare @Cnt int
    Set @Cnt = 1

    While (Charindex(@SplitOn,@RowData)>0)
    Begin
        Insert Into @RtnValue (data)
        Select 
            Data = ltrim(rtrim(Substring(@RowData,1,Charindex(@SplitOn,@RowData)-1)))

        Set @RowData = Substring(@RowData,Charindex(@SplitOn,@RowData)+1,len(@RowData))
        Set @Cnt = @Cnt + 1
    End

    Insert Into @RtnValue (data)
    Select Data = ltrim(rtrim(@RowData))

    Return
END

다음과 같은 방법으로 네 개의 밑줄을 찾을있습니다.

create table #test
( t varchar(50) );

insert into #test values 
( 'abc_1_2_3_4.gif'),
('zzz_12_3_3_45.gif');

declare @t varchar(50);
declare @t_aux varchar(50);
declare @t1 int;
declare @t2 int;
declare @t3 int;
declare @t4 int;

DECLARE t_cursor CURSOR
    FOR SELECT t FROM #test
OPEN t_cursor
FETCH NEXT FROM t_cursor into @t;​
set @t1 = charindex( '_', @t )
set @t2 = charindex( '_', @t , @t1+1)
set @t3 = charindex( '_', @t , @t2+1)
set @t4 = charindex( '_', @t , @t3+1)

select @t1, @t2, t3, t4

--do a loop to iterate over all table

여기서 테스트할 수 있습니다.

또는 다음과 같은 간단한 방법으로:

select 
  charindex( '_', t ) as first,
  charindex( '_', t, charindex( '_', t ) + 1 ) as second,
  ...
from 
  #test

리스트의 구별을 가정하여 변수/배열을 제거할 수 있습니다.

declare @array table   ----table of values
(
    id int identity(1,1)
    ,value nvarchar(max)
)
DECLARE @VALUE NVARCHAR(MAX)='val1_val2_val3_val4_val5_val6_val7'----string array
DECLARE @CURVAL NVARCHAR(MAX)     ---current value
DECLARE @DELIM NVARCHAR(1)='_'    ---delimiter
DECLARE @BREAKPT INT              ---current index of the delimiter 

WHILE EXISTS (SELECT @VALUE)  
    BEGIN
        SET @BREAKPT=CHARINDEX(@DELIM,@VALUE)   ---set the current index
        ---
        If @BREAKPT<> 0                          ---index at 0 breaks the loop
            begin
                SET @CURVAL=SUBSTRING(@VALUE,1,@BREAKPT-1)                  ---current value
                set @VALUE=REPLACE(@VALUE,SUBSTRING(@VALUE,1,@BREAKPT),'')  ---current value and delimiter, replace
                insert into @array(value)                                   ---insert data 
                select @CURVAL
            end
        else
            begin
                SET @CURVAL=@VALUE                                          ---current value now last value
                insert into @array(value)                                   ---insert data
                select @CURVAL
                break                                                       ---break loop
            end
    end

select * from @array    ---find nth occurance given the id
DECLARE @LEN INT
DECLARE @VAR VARCHAR(20)
SET @VAR = 'HELLO WORLD'
SET @LEN = LEN(@VAR)
--SELECT @LEN
SELECT PATINDEX('%O%',SUBSTRING(@VAR,PATINDEX('%O%' ,@VAR) +  1 ,PATINDEX('%O%',@VAR) + 1)) + PATINDEX('%O%',@VAR)

내 SQL은 하위 문자열_의 기능을 지원합니다.해당 항목에 대한 문자열의 값 위치를 반환할 인덱스입니다.이를 위해 유사한 사용자 정의 함수를 작성할 수 있습니다.링크의 예

또는 charindex 함수 호출을 x회 사용하여 이전에 찾은 인스턴스의 시작 위치 +1이 지정된 각 _의 위치를 보고할 수 있습니다.0이 발견될 때까지

편집: NM 문자 색인이 올바른 기능입니다.

나는 이것을 여러 개의 별도의 사용자 정의 함수를 만들었는데, 검색된 문자의 각 위치에 대해 하나씩 만들었습니다. 예를 들어, 두 번째, 세 번째:

CREATE FUNCTION [dbo].[fnCHARPOS2] (@SEARCHARVARCHAR(255), @SEARCHRING VARCHAR(255)) BEGIN RETURN CHARIND(@SEARCHAR, @SEARCHRING(CHARIND(@SEARCHAR, 0));

CREATE FUNCTION [dbo].[fnCHARPOS3]
(@SEARCHCHAR VARCHAR(255),
@SEARCHSTRING VARCHAR(255))
RETURNS INT
AS
BEGIN
 RETURN CHARINDEX(@SEARCHCHAR,@SEARCHSTRING,    (CHARINDEX(@SEARCHCHAR,@SEARCHSTRING,    (CHARINDEX(@SEARCHCHAR,@SEARCHSTRING,0)+1)))+1);

그런 다음 검색 중인 문자와 검색 중인 문자열을 매개 변수로 전달할 수 있습니다.

따라서 'f'를 검색할 때 처음 3번의 위치를 알고 싶다면 다음과 같이 하십시오.

select 
database.dbo.fnCHARPOS2('f',tablename.columnname),
database.dbo.fnCHARPOS3('f',tablename.columnname)
from tablename

저한테 효과가 있었어요!

저는 논리를 따르는 것이 더 쉬웠기 때문에 재귀 함수를 사용하기로 결정했습니다.SQL Server의 기본 기능 재귀 제한은 32이므로 이는 소규모 워크로드에만 적합합니다.

create function dbo._charindex_nth (
  @FindThis varchar(8000),
  @InThis varchar(max),
  @StartFrom int,
  @NthOccurence tinyint
)
returns bigint
as
begin
  /*
  Recursive helper used by dbo.charindex_nth to return the position of the nth occurance of @FindThis in @InThis

  Who   When    What
  PJR   160421  Initial   
  */

  declare @Pos bigint

  if isnull(@NthOccurence, 0) <= 0 or isnull(@StartFrom, 0) <= 0
  begin
    select @Pos = 0
  end else begin
    if @NthOccurence = 1
    begin
      select @Pos = charindex(@FindThis, @InThis, @StartFrom)
    end else begin
      select @Pos = dbo._charindex_nth(@FindThis, @InThis, nullif(charindex(@FindThis, @InThis, @StartFrom), 0) + 1, @NthOccurence - 1)
    end
  end

  return @Pos
end

create function dbo.charindex_nth (
  @FindThis varchar(8000),
  @InThis varchar(max),
  @NthOccurence tinyint
)
returns bigint
as
begin
  /*
  Returns the position of the nth occurance of @FindThis in @InThis

  Who   When    What
  PJR   160421  Initial   
  */

  return dbo._charindex_nth(@FindThis, @InThis, 1, @NthOccurence)
end

declare @val varchar(max) = 'zzz_12_3_3_45.gif'

select dbo.charindex_nth('_', @val, 1) Underscore1
  , dbo.charindex_nth('_', @val, 2) Underscore2
  , dbo.charindex_nth('_', @val, 3) Underscore3
  , dbo.charindex_nth('_', @val, 4) Underscore4
DECLARE @T AS TABLE(pic_name VARCHAR(100));
INSERT INTO @T VALUES ('abc_1_2_3_4.gif'),('zzz_12_3_3_45.gif');

SELECT A.pic_name, P1.D, P2.D, P3.D, P4.D 
FROM @T A
CROSS APPLY (SELECT NULLIF(CHARINDEX('_', A.pic_name),0) AS D)  P1
CROSS APPLY (SELECT NULLIF(CHARINDEX('_', A.pic_name, P1.D+1), 0) AS D)  P2
CROSS APPLY (SELECT NULLIF(CHARINDEX('_', A.pic_name, P2.D+1),0) AS D)  P3
CROSS APPLY (SELECT NULLIF(CHARINDEX('_', A.pic_name, P3.D+1),0) AS D)  P4

xml 변환을 사용하여 이 작업을 수행할 수 있는 간단한 샘플:

SELECT 'A|B|C' AS text
 , concat('<x>', REPLACE('A|B|C', '|', '</x><x>'), '</x>') AS xml
 , cast(concat('<x>', REPLACE('A|B|C', '|', '</x><x>'), '</x>') as xml).query('/x[2]') AS tag
 , cast(concat('<x>', REPLACE('A|B|C', '|', '</x><x>'), '</x>') as xml).value('/x[3]',     
   'varchar') AS char;

또는 다음과 같은 CTE/표에서 제공됩니다.

WITH data AS (
  SELECT 'A|B|C' AS text
)
SELECT concat('<x>', REPLACE(text, '|', '</x><x>'), '</x>') AS xml
 , cast(concat('<x>', REPLACE(text, '|', '</x><x>'), '</x>') as xml).query('/x[2]') AS tag
 , cast(concat('<x>', REPLACE(text, '|', '</x><x>'), '</x>') as xml).value('/x[2]',     
   'varchar') AS char
FROM Data 

돌아온다

xml 꼬리표를 달다
A </x><x>B </x>C </x> B </x> B

그리고 여기 당신의 샘플에 대한 번역이 있습니다.

SELECT gifname
      ,cast(concat('<x>', REPLACE(gifname, '_', '</x><x>'), '</x>') as xml).query('/x[2]') as xmlelement
     , cast(concat('<x>', REPLACE(gifname, '_', '</x><x>'), '</x>') as xml).value('/x[2]', 'varchar(10)') as result
    FROM (
      SELECT 'abc_1_2_3_4.gif' as gifname
      UNION ALL
      SELECT 'zzz_12_3_3_45.gif'
    ) tmp

나는 함수를 사용하여 구분된 문자열 필드에서 "n번째" 요소를 얻는 데 성공했습니다.위에서 언급한 것처럼, 그것은 일을 처리하는 "빠른" 방법은 아니지만 확실히 편리합니다.

create function GetArrayIndex(@delimited nvarchar(max), @index int,  @delimiter nvarchar(100) = ',')  returns nvarchar(max)  
as    
begin     
 declare @xml xml, @result nvarchar(max)  
 set @xml = N'<root><r>' + replace(@delimited, @delimiter,'</r><r>') + '</r></root>'  
 select @result = r.value('.','varchar(max)')   
 from @xml.nodes('//root/r[sql:variable("@index")]') as records(r)  

 return @result   
end    

저는 단순히 끈을 통해 반복하는 것보다 더 빠른 방법으로 이 일을 하고 있었습니다.

CREATE FUNCTION [ssf_GetNthSeparatorPosition] ( @TargetString VARCHAR(MAX)
                                              , @Sep VARCHAR(25)
                                              , @n INTEGER )
RETURNS INTEGER
/****************************************************************************************
--#############################################################################
-- Returns the position of the Nth Charactor sequence
--                                     1234567890123456789
-- Declare @thatString varchar(max) = 'hi,there,jay,yo'
  Select dbo.ssf_GetNthSeparatorPosition(@thatString, ',', 3) --would return 13
--############################################################################ 


****************************************************************************************/
AS
    BEGIN
        DECLARE @Retval INTEGER = 0
        DECLARE @CurPos INTEGER = 0
        DECLARE @LenSep INTEGER = LEN(@Sep)

        SELECT @CurPos = CHARINDEX(@Sep, @TargetString)

        IF ISNULL(@LenSep, 0) > 0
            AND @CurPos > 0
            BEGIN

               SELECT @CurPos = 0
              ;with lv0 AS (SELECT 0 g UNION ALL SELECT 0)
                            ,lv1 AS (SELECT 0 g FROM lv0 a CROSS JOIN lv0 b) -- 4
                            ,lv2 AS (SELECT 0 g FROM lv1 a CROSS JOIN lv1 b) -- 16
                            ,lv3 AS (SELECT 0 g FROM lv2 a CROSS JOIN lv2 b) -- 256
                            ,lv4 AS (SELECT 0 g FROM lv3 a CROSS JOIN lv3 b) -- 65,536
                            ,lv5 AS (SELECT 0 g FROM lv4 a CROSS JOIN lv4 b) -- 4,294,967,296
                            ,Tally (n) AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM lv5),
                        results
                          AS ( SELECT n - LEN(@Sep) AS Nth
                                ,   row_number() OVER ( ORDER BY n ) - 1 AS Position
                                FROM Tally t
                                WHERE n BETWEEN 1
                                        AND     DATALENGTH(@TargetString) + DATALENGTH(@Sep)
                                    AND SUBSTRING(@Sep + @TargetString, n, LEN(@Sep)) = @Sep)
                    SELECT @CurPos = Nth
                        FROM results
                        WHERE results.Position = @n


            END
        RETURN @CurPos

    END

GO
declare @a nvarchar(50)='Enter Your string '
declare @character char='e'
declare @nthoccurence int = 2
declare @i int = 1
declare @j int =0
declare @count int = len(@a)-len(replace(@a,@character,''))

if(@count >= @nthoccurence)
begin
        while (@I <= @nthoccurence)
        begin
            set @j= CHARINDEX(@character,@a,@j+1)
            set @i= @i+1
        end
        print @j
end
else
    Print 'you have only '+convert(nvarchar ,@count)+' occurrences of '+@character
end
DECLARE @x VARCHAR(32) = 'MS-SQL-Server';

SELECT 
SUBSTRING(@x,0,CHARINDEX('-',LTRIM(RTRIM(@x)))) A,
SUBSTRING(@x,CHARINDEX('-',LTRIM(RTRIM(@x)))+1,CHARINDEX('-' 
,LTRIM(RTRIM(@x)))) B,
SUBSTRING(@x,CHARINDEX('-',REVERSE(LTRIM(RTRIM(@x))))+1,LEN(@x)-1) C


A   B   C
MS  SQL Server

Alex K의 답변 OneWay (2k8)에서 영감을 받아 문자열에서 특정 토큰을 반환하는 SQL Server용 토큰 함수 스크립트를 만들었습니다.Alex의 솔루션을 여러 번 수동으로 구현할 필요 없이 SSIS 패키지를 T-SQL로 리팩터링하기 위해 필요했습니다.내 기능에는 한 가지 단점이 있습니다.토큰 값을 막대 값이 아닌 테이블(한 열, 한 행)로 반환합니다.이에 대한 해결책이 있는 사람이 있다면 저에게 알려주시기 바랍니다.

DROP FUNCTION [RDW].[token]
GO

create function [RDW].[token] (@string varchar(8000), @split varchar(50), @returnIndex int) 
returns table  
as 
    return with T(img, starts, pos, [index]) as ( 
        select @string, 1, charindex(@split, @string), 0 
        union all 
        select @string, pos + 1, charindex(@split, @string, pos + 1), [index]+1 
        from t 
        where pos > 0
    )
    select substring(img, starts, case when pos > 0 then pos - starts else len(img) end) token
    from T
    where [index] = @returnIndex 
GO

사용해 보세요.

CREATE FUNCTION [dbo].[CHARINDEX2] (
    @expressionToFind VARCHAR(MAX),
    @expressionToSearch VARCHAR(MAX),
    @occurrenceIndex INT,
    @startLocation INT = 0
)
RETURNS INT
AS BEGIN

IF @occurrenceIndex < 1 BEGIN
    RETURN CAST('The argument @occurrenceIndex must be a positive integer.' AS INT)
END

IF @startLocation < 0 BEGIN
    RETURN CAST('The argument @startLocation must be a non negative integer.' AS INT)
END

DECLARE @returnIndex INT

SET @returnIndex = CHARINDEX(@expressionToFind, @expressionToSearch, @startLocation)

IF (@occurrenceIndex = 1) BEGIN
    RETURN @returnIndex
END

DECLARE @target_length INT
SET @target_length = LEN(@expressionToFind)
SET @occurrenceIndex += -1

WHILE (@occurrenceIndex > 0 AND @returnIndex > 0) BEGIN
    SET @returnIndex = CHARINDEX(@expressionToFind, @expressionToSearch, @returnIndex + @target_length);
    SET @occurrenceIndex += -1
END

RETURN @returnIndex

END
GO

다음 기능을 사용합니다.

CREATE FUNCTION [pub].[SplitString] 
(   @StringToSplit nvarchar(MAX),
    @Delimiter as nvarchar(10) 
)

-- Example of use:
-- select * from [pub].[SplitString] ('one;two;three;;for & six;', ';')

RETURNS
    @returnList TABLE ([Item] [nvarchar] (4000), [ID] [int] IDENTITY(1,1))
AS
BEGIN
    DECLARE @xml as xml

    SET @xml = 
        cast
        (   ('<X>' + replace(replace(@StringToSplit, @Delimiter ,'</X><X>'),'&','&amp;') + '</X>'
            ) as xml
        )

    INSERT INTO @returnList([Item])
    SELECT 
        N.value('.', 'nvarchar(max)') as [Item] 
    FROM 
        @xml.nodes('X') as T(N)

    RETURN
END

이것이 질문에 직접적으로 답하지는 않지만, 특정 구분 기호를 사용하여 단일 문자열에서 여러 값을 추출하는 솔루션을 찾다가 이를 발견했기 때문에 누군가에게 도움이 될 경우를 대비하여 어쨌든 게시합니다.

SQL Server에는 오른쪽에서 점으로 구분된 문자열로 최대 4개의 요소를 추출할 수 있는 PARSNAME 기능이 함께 제공됩니다.

SELECT PARSENAME('1234.5437.43278.532', 2) as third_element
--43278

이 함수를 사용하여 확장자 없이 파일 이름의 두 번째 요소에서 끝까지 선택하여 파일 이름의 두 번째 요소에서 다섯 번째 요소를 검색할 수 있습니다.

파일 확장명(오른쪽에서 네 번째 위치)을 제거하는 코드는 여기에 하드 코딩되어 있으므로 예를 들어 .jpg 및 .jpeg 파일 확장명과 함께 사용하는 경우 변경하는 것이 좋습니다.

DECLARE @t TABLE (
  c_filename VARCHAR(1000)
) INSERT @t 
values 
  ('abc_1_2_3_4.gif'), 
  ('abcdefgh_1231_78432_398389_12144.png') 
SELECT 
  LEFT(
    c_filename, 
    CHARINDEX('_', c_filename) -1
  ) as first_element, 
  PARSENAME(
    REPLACE(
      /* PARSENAME only works with 4 elements */
      /* we remove :
      - the 1st element
      - and the file extension */
      SUBSTRING( 
        c_filename, 
        CHARINDEX('_', c_filename) + 1, 
        LEN(c_filename) - CHARINDEX('_', c_filename) -4
      ), 
      '_', 
      '.'
    ), 
    4 -- change this to get the nth element
  ) as second_element, 
  PARSENAME(
    REPLACE(
      SUBSTRING(
        c_filename, 
        CHARINDEX('_', c_filename) + 1, 
        LEN(c_filename) - CHARINDEX('_', c_filename) -4
      ), 
      '_', 
      '.'
    ), 
    3
  ) as third_element, 
  PARSENAME(
    REPLACE(
      SUBSTRING(
        c_filename, 
        CHARINDEX('_', c_filename) + 1, 
        LEN(c_filename) - CHARINDEX('_', c_filename) -4
      ), 
      '_', 
      '.'
    ), 
    2
  ) as fourth_element, 
  PARSENAME(
    REPLACE(
      SUBSTRING(
        c_filename, 
        CHARINDEX('_', c_filename) + 1, 
        LEN(c_filename) - CHARINDEX('_', c_filename) -4
      ), 
      '_', 
      '.'
    ), 
    1
  ) as fifth_element 
FROM 
  @t
+---------------+----------------+---------------+----------------+---------------+
| first_element | second_element | third_element | fourth_element | fifth_element |
+---------------+----------------+---------------+----------------+---------------+
| abc           | 1              |             2 |              3 |             4 |
| abcdefghijkl  | 12qwerty31     |      78891432 |      398977389 |    1212345344 |
+---------------+----------------+---------------+----------------+---------------+

언급URL : https://stackoverflow.com/questions/8726111/sql-server-find-nth-occurrence-in-a-string

반응형