{"id":225,"date":"2018-02-05T18:54:28","date_gmt":"2018-02-05T18:54:28","guid":{"rendered":"http:\/\/eipsoftware.com\/musings\/?p=225"},"modified":"2018-02-19T18:55:29","modified_gmt":"2018-02-19T18:55:29","slug":"oracle-pl-sql-subtotal-operators","status":"publish","type":"post","link":"https:\/\/eipsoftware.com\/musings\/oracle-pl-sql-subtotal-operators\/","title":{"rendered":"Oracle PL\/SQL Subtotal Operators"},"content":{"rendered":"<h4>Oracle PL\/SQL Subtotal Operators<\/h4>\n<p>There are times when we need not just the total value for the column, but subtotal values depending on different column values.\u00a0 Oracle supports subtotal operators through the three key operators they are <strong>CUBE, ROLLUP,\u00a0<\/strong>and\u00a0<strong>GROUPING SETS.<\/strong> Below are examples of each one and how best to use them.<\/p>\n<p><!--more--><\/p>\n<h5>Cube<\/h5>\n<p>Cube operator will provide subtotals for each interval of the non-aggregated columns in the <strong>SELECT<\/strong> statement.<\/p>\n<pre class=\"lang:plsql decode:true \">SELECT      calmonth\r\n            ,addrcatcode1\r\n            ,SUM(extcost)        AS sum_extcost\r\n            ,SUM(quantity)      AS sum_quantity\r\n            \r\nFROM        inventory_fact\r\n            INNER JOIN date_dim\r\n                ON inventory_fact.datekey = date_dim.datekey\r\n            INNER JOIN cust_vendor_dim\r\n                ON inventory_fact.custvendorkey = cust_vendor_dim.custvendorkey\r\nWHERE       transtypekey = 5 -- 'Sales Order Shipment'\r\n            AND date_dim.calyear = 2011\r\nGROUP BY    CUBE(calmonth\r\n            ,addrcatcode1\r\n            )\r\n;<\/pre>\n<p>The above example aggregates the extcost and quantity columns.\u00a0 And will provide not all the total values but the subtotal values for each month in calmonth and each value in addrcatcade1 column.<\/p>\n<h5>Rollup<\/h5>\n<p><strong>ROLLUP<\/strong> aggregates in a hierarchical method.\u00a0 It will show totals for the entire column and each level in the hierarchy. The hierarchy doesn&#8217;t have to be defined in the database.<\/p>\n<pre class=\"lang:plsql decode:true \">SELECT      companyname\r\n            ,bpname\r\n            ,SUM(extcost)        AS sum_extcost\r\n            ,SUM(quantity)      AS sum_quantity\r\nFROM        inventory_fact\r\n            INNER JOIN branch_plant_dim\r\n                ON inventory_fact.BRANCHPLANTKEY = branch_plant_dim.BRANCHPLANTKEY\r\n            INNER JOIN company_dim\r\n                ON branch_plant_dim.companykey = company_dim.COMPANYKEY\r\nWHERE       transtypekey = 2 -- 'Inventory Transfer'\r\nGROUP BY    ROLLUP(companyname\r\n            ,bpname)\r\nORDER BY    companyname, bpname\r\n;<\/pre>\n<p>The above example will show the totals for the column extcost and quantiy; and subtotals for each level of company and bpname. In the\u00a0<strong>ROLLUP<\/strong> operator you specify the hierarchy order. The first column listed is the highest level of the hierarchy and each subsequent column will be a lower level of the hierarchy.\u00a0 However it will not show a subtotal for levels of bpname by itself.\u00a0 If you need to see subtotals for each level of bpname you would either use <strong>CUBE<\/strong> or <strong>GROUPING SETS<\/strong>.<\/p>\n<h5>Grouping Sets<\/h5>\n<p><strong>GROUPING SETS<\/strong> are the most flexible of the subtotal operators where you can specify subtotals you want to see.<\/p>\n<pre class=\"lang:plsql decode:true \">SELECT      calquarter\r\n            ,zip\r\n            ,cust_vendor_dim.name\r\n            ,SUM(extcost)           AS sum_extcost\r\n            ,COUNT(inventorykey)    AS count_transactions\r\n\r\nFROM        inventory_fact\r\n            INNER JOIN date_dim\r\n                ON inventory_fact.datekey = date_dim.datekey\r\n            INNER JOIN cust_vendor_dim\r\n                ON inventory_fact.custvendorkey = cust_vendor_dim.custvendorkey\r\nWHERE       transtypekey = 5 -- 'Sales Order Shipment'\r\n            AND date_dim.calyear BETWEEN 2011 AND 2012\r\nGROUP BY    GROUPING SETS (\r\n            (calquarter,zip,cust_vendor_dim.NAME)\r\n            ,(calquarter, zip)\r\n            ,(CalQuarter,cust_vendor_dim.Name) \r\n            ,(cust_vendor_dim.Name,Zip) \r\n            ,CalQuarter\r\n            ,Zip\r\n            ,cust_vendor_dim.Name\r\n            ,())\r\n;<\/pre>\n<p>In the above example, in the\u00a0<strong>GROUPING SETS<\/strong> operator you specify which columns you want to calculate subtotals.\u00a0 You can specify as many or as few grouping sets as you want. If you want to see a total for the entire column then use an empty tuple, &#8220;()&#8221; in the list of tuples provided to the\u00a0<strong>GROUPING SETS<\/strong> operator.\u00a0 If you are calculating the subtotal based on the values in one column you can include or exclude the parenthesis. In the example above you can see this with ,calQuarter, Zip, cust_vendor_dim.Name.\u00a0 However if you are specifying subtotals be calculated using values from two or more columns they need to enclosed in parenthesis.<\/p>\n<p>I hope you found the above informative, let me know in the comments below.<\/p>\n<p><a href=\"mailto:michael.data@eipsoftware.com\">\u2014 michael.data@eipsoftware.com<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Oracle PL\/SQL Subtotal Operators There are times when we need not just the total value for the column, but subtotal values depending on different column values.\u00a0 Oracle supports subtotal operators through the three key operators they are CUBE, ROLLUP,\u00a0and\u00a0GROUPING SETS. Below are examples of each one and how best to use them.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[4,44,6],"tags":[14,30,48,49],"series":[],"class_list":["post-225","post","type-post","status-publish","format-standard","hentry","category-code","category-oracle-pl-sql","category-sql","tag-sql","tag-code","tag-pl-sql","tag-oracle"],"_links":{"self":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/225","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/comments?post=225"}],"version-history":[{"count":3,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/225\/revisions"}],"predecessor-version":[{"id":228,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/posts\/225\/revisions\/228"}],"wp:attachment":[{"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/media?parent=225"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/categories?post=225"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/tags?post=225"},{"taxonomy":"series","embeddable":true,"href":"https:\/\/eipsoftware.com\/musings\/wp-json\/wp\/v2\/series?post=225"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}