Quantcast
Channel: SQLServerCentral » Reporting Services » Reporting Services » Latest topics
Viewing all articles
Browse latest Browse all 2791

Filter based on range and multiple values

$
0
0
Given a single parameter, @SerialNumbersANDGiven a table with field SerialNumber with data type stringThe @SerialNumbers parameter is a text entry where the following are valid entries:Return Rows where SerialNumber is 1234 through 12401234,1235,1236,1237,1238,1239,1240 Return Rows where SerialNumber is 1234, 1236, 1250 through 1260, 1267, 1270 through 12991234,1236,1250-1260,1267,1270-1299I'm able to extract the values between the commas using a Tally table method, as described here: http://www.sqlservercentral.com/articles/Tally+Table/72993/But, taking it to the next level and handling the values that are "ranges"... I'm not sure how to do this.Here's what I have so far:[code="sql"] -- Return only the requested serial numbersWITH E1(N) AS ( SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 ), --10E+1 or 10 rows E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max cteTally(N) AS (--==== This provides the "base" CTE and limits the number of rows right up front -- for both a performance gain and prevention of accidental "overruns" SELECT TOP (ISNULL(DATALENGTH(@SerialNumber),0)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4 ),cteStart(N1) AS (--==== This returns N+1 (starting position of each "element" just once for each delimiter) SELECT 1 UNION ALL SELECT t.N+1 FROM cteTally t WHERE SUBSTRING(@SerialNumber,t.N,1) = ',' ),cteLen(N1,L1) AS(--==== Return start and length (for use in substring) SELECT s.N1, ISNULL(NULLIF(CHARINDEX(',',@SerialNumber,s.N1),0)-s.N1,8000) FROM cteStart s )--===== Do the actual split. The ISNULL/NULLIF combo handles the length for the final element when no delimiter is found. INSERT INTO @SerialTable (Serial) SELECT Serial = SUBSTRING(@SerialNumber, l.N1, l.L1) FROM cteLen l [/code]The code above create a table @SerialTable and populates it with the values specified as comma separated values from @SerialNumbersSo, with the above code and given @SerialNumbers=1234,1236,1250-1260,1267,1270-1299, @SerialTable would contain rows as follows:123412361250-126012671270-1299If I wanted to update @SerialTable to breakout rows 1250-1260 and 1270-1299 with the actual values, what's the most straightforward way to do this? Hopefully I don't need to use a for loop...

Viewing all articles
Browse latest Browse all 2791

Trending Articles