Discussions
Categories
Groups
Community Home
Categories
INTERNAL ENABLEMENT
POPULAR
PUBLIC CLOUD
PRIVATE CLOUD
Quick Links
MY LINKS
HELPFUL TIPS
Back to website
Home
Intelligence (Analytics)
How to display strings missing from sequence in report
bugsy
<p>I am very new to BIRT. I have a dataset that returns typeNames from a database query like so 'A22, A25, B3, B7'.</p>
<p> </p>
<p>What I need to display on the report are the typeNames, which I have from the query, and the typeNames that are missing from the sequence.</p>
<p> </p>
<p>So for the above I will also need to display 'Missing: A23, A24, B4, B5, B6' on the report.</p>
<p> </p>
<p>I have to figure out where to put code that can strip off that first character and sequence the numbers. And also how to reference them on the report once I do.</p>
<p> </p>
<p>I have been researching this for a couple of days and cannot figure out how to proceed.</p>
<p> </p>
<p>I would appreciate any suggestions. Thank you.</p>
Find more posts tagged with
Comments
JFreeman
<p>You should be able to use a persistent global variable.</p>
<p>You can create it in the beforeOpen of the data set.</p>
<p>In the onFetch of the data set you can populate it with the typeNames.</p>
<p> </p>
<p>Then, you can create a text element in the report and iterate through the persistent global variable in the onCreate of the text element. While iterating through you can use some logic to determine which values are missing and then set the text of the text element to display the desired values.</p>
PaulCooper
<p>You can also do this via SQL, although the exact details varies depending on the database type the essence is described below:</p>
<p> </p>
<p>Assuming your original SQL is (select typeName, ... from ....) then your SQL would be:</p>
<p> </p>
<p>with d as (select ... "typeName", ... from ....),</p>
<p>c1 as (select c.*,<br>
row_number() over (order by "prefix" asc) "order_num"</p>
<p> from (select left(typeName, 1) "prefix",</p>
<p> min(to_number(substr(typeName, 2, length(typeName)))) "min_n",</p>
<p> max(to_number(substr(typeName, 2, length(typeName)))) "max_n" from d group by left(typeName, 1)) c),</p>
<p>c2 as (select c1.*,</p>
<p>(select sum(c1_2."max_n" - c1_2."min_n" + 1) from c1 c1_2 where c1_2."order_num" < c1."order_num") "offset",</p>
<p>(select sum(c1_2."max_n" - c1_2."min_n" + 1) from c1 c1_2 where c1_2."order_num" <= c1."order_num") "range_max"</p>
<p>from c1),</p>
<p>range as (select LEVEL "num" from DUAL connect by LEVEL<=(select sum(c1."max_n" - c1."min_n" + 1) from c1)),</p>
<p>range2 as (select concat(c2."prefix", (range."num" - c2.offset)) "typeName2"</p>
<p>from range, c2</p>
<p>where range."num" > c2."offset" and range."num" <= c2."range_max")</p>
<p>select range2."typeName2", d.*</p>
<p>from d left join range2 on range2."typeName2" = d."typeName"</p>
<p> </p>
<p>d is the original data set</p>
<p>c1 groups the typeName by its extracted prefix and calculates the max and min of the typeName number and gives a row number for the prefix</p>
<p>c2 is c1 plus calculations to give 1) the number of distinct typeNames that come before this typeName prefix and 2) the number of distinct typeNames that come before this typeName prefix and include this typeName prefix.</p>
<p>range gives a sequence from 1 to the number of distinct typeNames including missing ones.</p>
<p>range2 takes the number from range and offset and range_max from c2 and creates a list of typeNames including the missing ones.</p>
<p>range2 is then left joined to the original data set (d) to duplicate the original data set (d) and adding a single row for each missing typeName with all the fields other than typeName2 blank.</p>
<p> </p>
<p>The SQL above was written for Oracle so if you use some other database then you need to change the "range" SQL (See <a data-ipb='nomediaparse' href='
http://sqlbisam.blogspot.co.uk/2014/01/generate-series-or-list-of-numbers.html'>http://sqlbisam.blogspot.co.uk/2014/01/generate-series-or-list-of-numbers.html</a>
; for the t-sql version) some function such as to_number are different for other databases. Also some databases may not support analytical functions such as row_number() over (...)</p>
<p> </p>
<p>Finally I have to say I haven't tested the above SQL but it was only met to be for demonstration purposes.</p>
bugsy
<p>Sorry to be so late to reply. Have been off this. Thank you for the assistance. I decided the sql approach would work better for me although I wished to have a more BIRT solution.</p>
<p> </p>
<p>I decided to use a cursor, although it would not have been my first choice I needed to get something working.</p>
<p> </p>
<p> SELECT to_number(substr(the_num,2)) after_gap, substr(the_number,1,1) gap_char,<br>
LAG(to_number(substr(the_num,2)),1,0) OVER (ORDER BY substr(the_number,1,1)) before_gap,<br>
LAG(substr(the_num,1,1),1,'0') OVER (ORDER BY substr(the_num,1,1)) prev_char</p>
<p> </p>
<p>Again thank you for the responses.</p>