Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server - find nth occurrence in a string

Tags:

sql-server

I have a table column that contains values such as abc_1_2_3_4.gif or zzz_12_3_3_45.gif etc.

I want to find the index of each underscore _ in the above values. There will only ever be four underscores but given that they can be in any position in the string, how can I achieve this?

I've tried the substring and charindex function, but I can only reliably get hold of the first one. Any ideas?

like image 343
adrianos Avatar asked Jan 04 '12 11:01

adrianos


People also ask

How do you find the nth occurrence of a character in a string in SQL?

T-SQL's CHARINDEX() function is a useful for parsing out characters within a string. However, it only returns the first occurrence of a character. Oftentimes one needs to locate the Nth instance of a character or a space, which can be a complicated task in standard T-SQL.

How do you find 2nd occurrence of a character in a string in SQL Server?

For example, to find the second occurrence of 'B' in the source string 'ABCABC', we could use SELECT LOCATE('B', 'ABCABC', LOCATE('B', 'ABCABC') + 1) + LOCATE('B', 'ABCABC') FROM SYSIBM/SYSDUMMY1 that will return 5. In this case, we used the “second” locate in the list to find the first “B” in the string, which was 2.


1 Answers

One way (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 

Update

;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 
like image 76
Alex K. Avatar answered Sep 20 '22 06:09

Alex K.