I have the following strings
KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52
IYT_2012_CBBI1_S_66_2012-09-21_15_28_53
I want to extract everything after the 1st _ & before the 5th _
ex:
2012_CBBE2_E_12704
2012_CBBI1_S_66
I have the following strings
KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52
IYT_2012_CBBI1_S_66_2012-09-21_15_28_53
I want to extract everything after the 1st _ & before the 5th _
ex:
2012_CBBE2_E_12704
2012_CBBI1_S_66
Use CHARINDEX('_', stringvalue) to get the position of the first _ in stringvalue. You can instruct CHARINDEX to start searching from a certain position, if you pass that position as the third argument:
CHARINDEX(`_`, stringvalue, startpos)
Now, if the starting position will be the result of CHARINDEX('_', stringvalue)+1, i.e. like this:
CHARINDEX(`_`, stringvalue, CHARINDEX(`_`, stringvalue) + 1)
then that will give you the second _'s position. So, to find the fifth _, you'll need to nest CHARINDEX three more times:
WITH aTable AS (
SELECT
*
FROM
(VALUES
('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52'),
('IYT_2012_CBBI1_S_66_2012-09-21_15_28_53')
) AS v (aStringColumn)
),
positions AS (
SELECT
aStringColumn,
Underscore1 = CHARINDEX('_', aStringColumn),
Underscore5 = CHARINDEX('_',
aStringColumn,
CHARINDEX('_',
aStringColumn,
CHARINDEX('_',
aStringColumn,
CHARINDEX('_',
aStringColumn,
CHARINDEX('_',
aStringColumn
) + 1
) + 1
) + 1
) + 1
)
FROM
aTable
)
SELECT
aSubstring = SUBSTRING(aStringColumn,
Underscore1 + 1,
Underscore5 - Underscore1 - 1
)
FROM
positions
;
Use a numbers table to split every string into single characters, pulling their positions along the way.
Rank every character's occurrence in the string.
Get two subsets:
1) with the character _ and the ranking of 1;
2) with the character _ and the ranking of 5.
Join these subsets with each other.
Use the corresponding positions of _ #1 and _ #5 similarly to Method 1 to get the substring(s).
WITH aTable AS (
SELECT
*
FROM
(VALUES
('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52'),
('IYT_2012_CBBI1_S_66_2012-09-21_15_28_53')
) AS v (aStringColumn)
),
split AS (
SELECT
t.aStringColumn,
aChar = SUBSTRING(t.aStringColumn, n.Number, 1),
Position = n.Number
FROM
aTable t
INNER JOIN Numbers n
ON n.Number BETWEEN 1 AND LEN(t.aStringColumn)
),
ranked AS (
SELECT
*,
rnk = ROW_NUMBER() OVER (PARTITION BY aStringColumn, aChar ORDER BY Position)
FROM
split
WHERE
aChar = '_'
)
SELECT
aSubstring = SUBSTRING(first.aStringColumn,
first.Position + 1,
fifth.Position - first.Position - 1
)
FROM
ranked first
INNER JOIN ranked fifth
ON first.aStringColumn = fifth.aStringColumn
WHERE
first.rnk = 1
AND fifth.rnk = 5
;
Note: both methods assume that every aStringColumn value does have at least 5 underscore characters.
It's cunningly named SubString
as in
Select Substring('KLPI_2012_CBBE2_E_12704_2012-09-21_13_59_52',6,18)
If you want to find it within the string, then CharIndex would be useful. Are you sure you want to do this in SQL, it's going to be messy and slow and you'll need to create a UDF, or use CLR to make any real use of it.