I'm creating a report for a business using Oracle and SSRS. The report requires me to aggregate contiguous ranges of serial numbers, which can consist of alphanumerics.
For example, say I have the following serials:
OPS114
OPS115
OPS116
OPS117
OPS145
OPS146
OPS160
890RPT
896RPT
897RPT
The report should have a single aggregate row for each contiguous range, with the count of each range, like so:
OPS114 - OPS117 (4)
OPS145 - OPS146 (2)
OPS160 - OPS160 (1)
890RPT - 890RPT (1)
896RPT - 897RPT (2)
I've pulled the data I need, and I'm bulk-collecting it into a table variable. Now, I need to aggregate the rows - this wouldn't be bad if I only needed to manipulate the data, but I need to have this available as a query for the refcursor. Can I open a refcursor for a PL/SQL FOR loop, or am I barking up the wrong tree? I've attempted to Google this, but the "cursor for loop" is not what I'm looking for. The alternative is to try to aggregate the results in SSRS using VB. (So either way, it won't be a good time.) I'm not sure if I have access to create a SQL table type for this, so this is the alternative I've sought.
If anyone has any experience with this, it would be greatly appreciated!
You could do this from a single SQL statement but you need to define the data better. Your column stores strings but you are using them as numbers to find out the range. And it seems the number part could either be before or after the string part.
If you are able to write some logic that separates out the numbers like this (and maybe keep the string part in another column)-
114
115
116
117
145
146
160
890
896
897
Then it reduces to a simple gaps and islands problem.
Step 1 - Select rownum along with this column (this would be a continuous sequence starting from 1)
Step 2 - Subtract rownum from this numeric data column.
Step 3 - Group by that result
Step 4 - Get min(numeric value) and max(numeric value) and count(numeric value) from the group which will be your result when combined as string.
Numeric_part Rownum Difference
------------ ------ ------------
114 1 113
115 2 113
116 3 113
117 4 113
145 5 140
146 6 140
160 7 153
890 8 882
896 9 887
897 10 887
Grouping this by Difference column, you get -
Difference Min(num) Max(num) count(num) Result
---------- --------- ---------- ---------- -----------------
113 114 117 4 114 - 117 (4)
140 145 146 2 145 - 146 (2)
153 160 160 1 160 - 160 (1)
882 890 890 1 890 - 890 (1)
887 896 897 2 896 - 897 (2)
That SQL statement can be used in PLSQL to return a cursor as in this link that @MickMnemonic has in the comments.
Basically -
OPEN cursor_variable FOR SELECT something FROM something...;