How to substring string value in SQL Server 2008
sql-server-2008
Solution
Method 1. Nested CHARINDEX calls.
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
;
Method 2. Character split + ranking.
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.
Problem
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 ```