As everyone said, it hurts to do this in SQL Server. If you should , I think this is the right approach.
First, define your own rules for parsing the string, then break the process down into clearly defined and understandable problems.
Based on your example, I think this is a process:
- Separate values, separated by commas, per line per line
- If the data does not contain , it ends (this is a separate value)
- If there is a dash in it, analyze the left and right sides of the dash
- Given that the left and right sides (range) determine all the values โโbetween them in a row
I would create a temporary table to populate the parsing results that need two columns:
SourceRowID INT, ContainedValue INT
and the other for intermediate processing:
SourceRowID INT, ContainedValues VARCHAR
Separate comma separated values โโinto your own lines using CTE, as this Step 1 is now a well-defined and understandable problem to solve :
Include comma separated line in separate lines
So your result from the source is '1-2,5'
will be:
'1-2'
'5'
From there, the SELECT from this processing table, in which the field does not contain , contains a dash. Step 2 is now a well-defined and understandable problem to solve . These are stand-alone numbers and can go directly to the temp results table. The result table should also have an identifier reference to the source row.
Next, analyze the values โโto the left and right of the dash using CHARINDEX to find it, then the corresponding LEFT and RIGHT functions will be executed as needed. This will give you the start and end value.
Here's an important question to solve this step 3 - this is now a clearly defined and understandable problem to solve :
T-SQL Substring - Separating First and Last Name
Now you have separated the start and end values. Use another function that can explode this range. Step 4 is a clear and understandable problem to solve :
SQL: create a sequential list of numbers from different launch points
SELECT all N between @min and @max
What is the best way to create and populate a number table?
and also insert it into the temp table.
Now what you need is a temporary table with each value in an exploded range.
Just JOIN that in another table of values โโnow, and then to the source table by reference ID and you are there.