{"id":472,"date":"2010-04-16T15:49:39","date_gmt":"2010-04-16T15:49:39","guid":{"rendered":"http:\/\/bar-solutions.com\/weblog\/?p=472"},"modified":"2010-04-16T15:49:39","modified_gmt":"2010-04-16T14:49:39","slug":"","status":"publish","type":"post","link":"https:\/\/blog.bar-solutions.com\/?p=472","title":{"rendered":"Report in APEX"},"content":{"rendered":"<p>The other day someone at a customer had a question about displaying a report. The different options are in a table so he could easily use a report to display the options. But he wanted to display three columns of options. That is, if there are 10 options, he would want to display 3 rows of 3 options and a single row of 1 option.<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"60\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"58\">option 1<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 2<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 4<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 5<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 7<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 8<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 9<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 10<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>should be displayed as:<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"164\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"58\">option 1<\/td>\n<td valign=\"top\" width=\"54\">option 2<\/td>\n<td valign=\"top\" width=\"50\">option 3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 4<\/td>\n<td valign=\"top\" width=\"54\">option 5<\/td>\n<td valign=\"top\" width=\"50\">option 6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 7<\/td>\n<td valign=\"top\" width=\"54\">option 8<\/td>\n<td valign=\"top\" width=\"50\">option 9<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"58\">option 10<\/td>\n<td valign=\"top\" width=\"54\">&#160;<\/td>\n<td valign=\"top\" width=\"50\">&#160;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>How can this be done. The answer is in the query.<\/p>\n<p><!--more--><\/p>\n<p>I decided to try some stuff and came up with the solution. First I need about 10 records.<br \/>\n  <br \/><font size=\"2\" face=\"Courier New\">SELECT rownum rn FROM user_source WHERE rownum &lt; 11;<\/font><\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"12\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">2<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">4<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">5<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">7<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">8<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">9<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">10<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Using subquery factoring helps me build the query step by step. Next, I need to split the results into three groups. Using the MOD function I can tell in which group a record should reside.<\/p>\n<p><font size=\"2\" face=\"Courier New\">WITH t AS<br \/>\n    <br \/> (SELECT rownum rn FROM user_source WHERE rownum &lt; 11)<br \/>\n    <br \/>select MOD(rn,3) rn2<br \/>\n    <br \/>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rn from t;<\/font><\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"22\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"10\">1<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">2<\/td>\n<td valign=\"top\" width=\"10\">2<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">0<\/td>\n<td valign=\"top\" width=\"10\">3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"10\">4<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">2<\/td>\n<td valign=\"top\" width=\"10\">5<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">0<\/td>\n<td valign=\"top\" width=\"10\">6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"10\">7<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">2<\/td>\n<td valign=\"top\" width=\"10\">8<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">0<\/td>\n<td valign=\"top\" width=\"10\">9<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"10\">10<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Now I want to split the results into different sets. Let\u2019s begin by creating a set of the first records.<\/p>\n<p><font size=\"2\" face=\"Courier New\">WITH t AS<br \/>\n    <br \/> (SELECT rownum rn FROM user_source WHERE rownum &lt; 11),<\/p>\n<p>x AS<\/p>\n<p> (SELECT MOD(rn<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,3) rn2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rn<\/p>\n<p>&#160;&#160;&#160; FROM t)<\/p>\n<p> SELECT rn&#160;&#160;&#160;&#160; v1<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r1<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 1<\/font>;<\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"26\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"14\">1<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">4<\/td>\n<td valign=\"top\" width=\"14\">2<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">7<\/td>\n<td valign=\"top\" width=\"14\">3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">10<\/td>\n<td valign=\"top\" width=\"14\">4<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>If I create three set of data (unique) then I can join them again<\/p>\n<p><font size=\"2\" face=\"Courier New\">WITH t AS<br \/>\n    <br \/> (SELECT rownum rn FROM user_source WHERE rownum &lt; 11),<\/p>\n<p>x AS<\/p>\n<p> (SELECT MOD(rn,3) rn2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rn<\/p>\n<p>&#160;&#160;&#160; FROM t),<\/p>\n<p>all1 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v1<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r1<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 1),<\/p>\n<p>all2 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r2<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 2),<\/p>\n<p>all3 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v3<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r3<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 0)<\/p>\n<p>SELECT v1<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; ,v2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; ,v3<\/p>\n<p>&#160; FROM all1<\/p>\n<p>&#160; JOIN all2 ON (r1 = r2)<\/p>\n<p>&#160; JOIN all3 ON (r2 = r3);<\/font><\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"32\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"10\">2<\/td>\n<td valign=\"top\" width=\"10\">3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">4<\/td>\n<td valign=\"top\" width=\"10\">5<\/td>\n<td valign=\"top\" width=\"10\">6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">7<\/td>\n<td valign=\"top\" width=\"10\">8<\/td>\n<td valign=\"top\" width=\"10\">9<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>What happened to number 10? The records don\u2019t always exist in the second and third set, so I have to use an outer join to see all the records available.<\/p>\n<p><font size=\"2\" face=\"Courier New\">WITH t AS<br \/>\n    <br \/> (SELECT rownum rn FROM user_source WHERE rownum &lt; 11),<\/p>\n<p>x AS<\/p>\n<p> (SELECT MOD(rn,3) rn2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rn<\/p>\n<p>&#160;&#160;&#160; FROM t),<\/p>\n<p>all1 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v1<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r1<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 1),<\/p>\n<p>all2 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r2<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 2),<\/p>\n<p>all3 AS<\/p>\n<p> (SELECT rn&#160;&#160;&#160;&#160; v3<\/p>\n<p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; ,rownum r3<\/p>\n<p>&#160;&#160;&#160; FROM x<\/p>\n<p>&#160;&#160; WHERE rn2 = 0)<\/p>\n<p>SELECT v1<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; ,v2<\/p>\n<p>&#160;&#160;&#160;&#160;&#160; ,v3<\/p>\n<p>&#160; FROM all1<\/p>\n<p>&#160; LEFT OUTER JOIN all2 ON (r1 = r2)<\/p>\n<p>&#160; LEFT OUTER JOIN all3 ON (r2 = r3);<\/font><\/p>\n<table border=\"1\" cellspacing=\"1\" cellpadding=\"1\" width=\"34\">\n<tbody>\n<tr>\n<td valign=\"top\" width=\"10\">1<\/td>\n<td valign=\"top\" width=\"12\">2<\/td>\n<td valign=\"top\" width=\"10\">3<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">4<\/td>\n<td valign=\"top\" width=\"12\">5<\/td>\n<td valign=\"top\" width=\"10\">6<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">7<\/td>\n<td valign=\"top\" width=\"12\">8<\/td>\n<td valign=\"top\" width=\"10\">9<\/td>\n<\/tr>\n<tr>\n<td valign=\"top\" width=\"10\">10<\/td>\n<td valign=\"top\" width=\"12\">&#160;<\/td>\n<td valign=\"top\" width=\"10\">&#160;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Now the result is exactly the way I (or actually the customer) wanted. All that needs to be done now is adapt this query so that it uses the real data. But the idea is in place.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The other day someone at a customer had a question about displaying a report. The different options are in a table so he could easily use a report to display the options. But he wanted to display three columns of options. That is, if there are 10 options, he would want to display 3 rows [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[16,2,9],"tags":[],"class_list":["post-472","post","type-post","status-publish","format-standard","hentry","category-apex","category-oracle","category-sql"],"_links":{"self":[{"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=\/wp\/v2\/posts\/472","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=472"}],"version-history":[{"count":0,"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=\/wp\/v2\/posts\/472\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=472"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=472"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.bar-solutions.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=472"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}