Reputation: 2141
I have a table of Companies and Invoices. My query sums the total values of each companies invoices to provide a 'total sales' by company. What I want to return is the +/- of each companies sales compared to the other companies in the same query.
Select Company.name, sum(Invoice.total) as InvoiceTotal
From Company
Inner Join Invoice on Invoice.CompanyId = Company.Id
Group By Company.name
Assuming The Above Query Produces:
Company InvoiceTotal
A 100
B 200
C 600
I want the additional column to provide the amount over or under the average of the InvoiceTotal column:
Company InvoiceTotal Difference
A 100 -200
B 200 -100
C 600 300
How can I extract that value in a single query?
Upvotes: 1
Views: 81
Reputation: 425
The results can be achieved using the query below:
Select Company.company, sum(Invoice.total) as InvoiceTotal, (SELECT AVG(Invoice.total) FROM Invoice) AS InvoiceAvg,(SELECT AVG(Invoice.total) FROM Invoice) -sum(Invoice.total) AS Difference
From Company
Inner Join Invoice on Invoice.CompanyId = Company.Id
Group By Company.company
Upvotes: 0
Reputation: 976
Here's another way to get the variance you're looking for
Select
name,
InvoiceTotal,
InvoiceTotal - avg(InvoiceTotal) as Difference
From
(Select Company.name, sum(Invoice.total) as InvoiceTotal
From Company
Inner Join Invoice on Invoice.CompanyId = Company.Id
Group By Company.name)
group by name, InvoiceTotal
Upvotes: 0
Reputation: 2572
Assuming your database supports CTE
with total as (
select avg(invoicetotal) totalsum
from table_name)
select t.company,
t.invoicetotal,
t.invoicetotal - total.totalsum
from table_name t, total
Company INVOICETOTAL T.INVOICETOTAL-TOTAL.TOTALSUM
A 100 -200
B 200 -100
C 600 300
Upvotes: 1
Reputation: 14199
If your database can handle windowed averages (most do), you can use a windowed average function thats applied to the sum of invoices, then do the rest with the sum of invoice.
This is an example with SQL Server:
;WITH Data AS
(
SELECT
*
FROM
(
VALUES
('a', 50),
('a', 25),
('a', 25),
('b', 125),
('b', 75),
('c', 275),
('c', 50),
('c', 75),
('c', 200)) V(Company, Invoice)
)
SELECT
Company = V.Company,
Invoice = SUM(V.Invoice),
AverageAcrossAllCompanies = AVG(SUM(V.Invoice)) OVER (),
AverageInvoiceDifference = SUM(V.Invoice) - AVG(SUM(V.Invoice)) OVER ()
FROM
Data AS V
GROUP BY
V.Company
Results:
Company Invoice AverageAcrossAllCompanies AverageInvoiceDifference
a 100 300 -200
b 200 300 -100
c 600 300 300
Upvotes: 1