简体   繁体   中英

sql group by sum of all sums

I have a query (formatted for Oracle):

select sum(inv.quantity * inv.price), spn.salesperson_name
from invoice inv
inner join salesperson spn on spn.spn_id = inv.spn_id
where inc.invoice_date between to_date('05/01/2017', 'MM/dd/YYYY') and to_date('05/31/2017', 'MM/dd/YYYY') 
group by spn.salesperson_name

To add up invoices for the month of May. The result is similar to:

$446,088.62     Bob
$443,439.29     Sally
$275,097.00     Tom
 $95,170.00     George
 $53,150.00     Jill

But, I need to divide each sum to the sum of the sums ($1,312,944.91), so that the result is:

$446,088.62     34%  Bob
$443,439.29     34%  Sally
$275,097.00     21%  Tom
 $95,170.00      7%  George
 $53,150.00      4%  Jill

(The sum of the percentage column should be 100%)

Is there a way to accomplish this in the query?

Just use analytic functions:

select spn.salesperson_name, sum(inv.quantity * inv.price), 
       sum(inv.quantity * inv.price)  / sum(sum(inv.quantity * inv.price)) over () as ratio 
from invoice inv inner join
     salesperson spn
     on spn.spn_id = inv.spn_id
where inc.invoice_date between date '2017-05-01' and date '2017-05-31'
group by spn.salesperson_name;

When functions exist that do exactly what you need, it is best to use those functions. In this case, the SQL Standard analytic function RATIO_TO_REPORT (which is implemented at least in Oracle and SQL Server) does exactly what you need. https://docs.oracle.com/cd/B19306_01/server.102/b14200/functions124.htm

Specifically, the select clause could be:

select sum(inv.quantity * inv.price) AS TOTAL_REVENUE   --  use column aliases!
     , ratio_to_report(sum(inv.quantity * inv.price)) over () AS RATIO,
     , spn.salesperson_name
from   .......   (rest of your query goes here)

Note that this solution, like the Accepted Answer, will show the ratio as a decimal, not as a percentage (and not rounded). If you need to attach a percentage sign, you will need to convert to string... and if so, the following trick (it is a trick!) will give you what you need:

to_char( ratio_to_report(.....), 'fm99L', 'nls_currency = %' ) AS RATIO, .....

The L element in to_char is for currency symbol; you define the currency symbol to be the percent sign.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM