Search code examples
sqloracle-databaserollup

data feed for reporting table in oracle (rollup vs grouping sets)


I have a query:

select country_region, 
       country_subregion, 
       country_name, 
       calendar_year, 
       calendar_quarter_number, 
       sum(amount_sold) as amount
  from countries co join
       customers cu on co.country_id = cu.country_id join
       sales sa on cu.cust_id = sa.cust_id join
       times ti on sa.time_id = ti.time_id
 where (   co.country_region = 'Americas' 
        or co.country_region = 'Middle East'
       ) 
   and ti.calendar_year between 2000 and 2001
group by grouping sets 
(
    (country_region, country_subregion, country_name, calendar_year, calendar_quarter_number),
    (country_region, country_subregion, country_name, calendar_year),
    (country_region, country_subregion, country_name),
    (country_region, country_subregion, calendar_year, calendar_quarter_number),
    (country_region, country_subregion, calendar_year),
    (country_region, country_subregion),
    (country_region, calendar_year, calendar_quarter_number),
    (country_region, calendar_year),
    (country_region),
    (calendar_year, calendar_quarter_number),
    (calendar_year),
    ()
)
order by amount desc;

What would be the query that returns the same output but uses group by rollup clause. I want to have a single query.


Solution

  • The equivalent query using the ROLLUP clause, is this:

    select country_region
         , country_subregion
         , country_name
         , calendar_year
         , calendar_quarter_number
         , sum(amount_sold) as amount
      from countries co
           join customers cu on co.country_id = cu.country_id
           join sales sa on cu.cust_id = sa.cust_id
           join times ti on sa.time_id = ti.time_id
     where (  co.country_region='Americas'
           or co.country_region='Middle East'
           )
       and ti.calendar_year between 2000 and 2001
     group by rollup (country_region, country_subregion, country_name)
         , rollup (calendar_year, calendar_quarter_number)
     order by amount desc
    

    Here is the proof:

     group by rollup (country_region, country_subregion, country_name)
         , rollup (calendar_year, calendar_quarter_number)
    

    equals

     group by grouping sets
           ( (country_region, country_subregion, country_name)
           , (country_region, country_subregion)
           , (country_region)
           , ()
           )
         , grouping sets
           ( (calendar_year, calendar_quarter_number)
           , (calendar_year)
           , ()
           )
    

    which equals

     group by grouping sets
           ( (country_region, country_subregion, country_name, calendar_year, calendar_quarter_number)
           , (country_region, country_subregion, country_name, calendar_year)
           , (country_region, country_subregion, country_name)
           , (country_region, country_subregion, calendar_year, calendar_quarter_number)
           , (country_region, country_subregion, calendar_year)
           , (country_region, country_subregion)
           , (country_region, calendar_year, calendar_quarter_number)
           , (country_region, calendar_year)
           , (country_region)
           , (calendar_year, calendar_quarter_number)
           , (calendar_year)
           , ()
           )
    

    which equals your original query.

    You can find more information about the group by extensions in this article that I wrote last year: http://www.rwijk.nl/AboutOracle/All_About_Grouping.pdf

    Regards, Rob.