Reputation: 407
So i am trying to get a sum of all balances for customers. What i want to do is get a total of all the values based on their Currency, for example if 3 customers had money in GBP like 1,2 and 3, the total price based on currency would be 6 as a total.
What I Have Tried
For the data to look visually appealing i have been able to use a Pivot function, making the Currency columns appear as Columns instead of rows like so:
SELECT *
FROM
(
SELECT DISTINCT Customer AS Total
, Currency
, Balances
FROM #temptable
) SRC
PIVOT
(
SUM(Balances)
FOR [Currency] IN ([AUD],[CAD],[EUR],[GBP])
) AS P
but it returns as this:
AUD CAD EUR GBP
CUS1 451 122
CUS2 213
CUS3 211 154
CUS4 123
I just want to have a row with the totals of all currencies
Upvotes: 0
Views: 328
Reputation: 69769
If you want to use the pivot function, you must create your totals within the subquery before you can pivot them, which you can do with GROUPING SETS
, for example,
-- DUMMY DATA
CREATE TABLE #temptable (Customer CHAR(4), Currency CHAR(3), Balances INT);
INSERT #TempTable (Customer, Currency, Balances)
VALUES
('CUS1', 'AUD', 451), ('CUS1', 'EUR', 122), ('CUS2', 'CAD', 213),
('CUS3', 'CAD', 211), ('CUS3', 'GBP', 154), ('CUS4', 'GBP', 123);
-- ACUTAL QUERY
SELECT ISNULL(CONVERT(VARCHAR(20), Customer), 'Column Total') AS Total
, ISNULL(CONVERT(VARCHAR(20), Currency), 'RowTotal') AS Currency
, SUM(Balances) AS Balances
FROM #temptable t
GROUP BY GROUPING SETS ((Customer, Currency), (Customer), (Currency), ());
You get your totals (I have separated out each grouping set for ease of understanding)
Total Currency Balances
------------------------------------
-- Grouping set (Customer, Currency)
CUS1 AUD 451
CUS2 CAD 213
CUS3 CAD 211
CUS1 EUR 122
CUS3 GBP 154
CUS4 GBP 123
-- Grouping set (Customer)
CUS1 RowTotal 573 -- TOTAL FOR CUS1
CUS2 RowTotal 213 -- TOTAL FOR CUS1
CUS3 RowTotal 365 -- TOTAL FOR CUS1
CUS4 RowTotal 123 -- TOTAL FOR CUS1
-- Grouping set (Currency)
Column Total AUD 451 -- TOTAL FOR AUD
Column Total CAD 424 -- TOTAL FOR CAD
Column Total EUR 122 -- TOTAL FOR EUR
Column Total GBP 277 -- TOTAL FOR GBP
-- Grouping set ()
Column Total RowTotal 1274 -- GRAND TOTAL
Then you do your pivot:
SELECT *
FROM
(
SELECT ISNULL(CONVERT(VARCHAR(20), Customer), 'Column Total') AS Total
, ISNULL(CONVERT(VARCHAR(20), Currency), 'RowTotal') AS Currency
, SUM(Balances) AS Balances
FROM #temptable
GROUP BY GROUPING SETS ((Customer, Currency), (Currency), (Customer), ())
) SRC
PIVOT
(
SUM(Balances)
FOR [Currency] IN ([AUD],[CAD],[EUR],[GBP],[RowTotal])
) AS P;
Which gives:
Total AUD CAD EUR GBP RowTotal
------------------------------------------------------------
Column Total 451 424 122 277 1274
CUS1 451 NULL 122 NULL 573
CUS2 NULL 213 NULL NULL 213
CUS3 NULL 211 NULL 154 365
CUS4 NULL NULL NULL 123 123
I wasn't sure which total you needed, so added both, but you should be able to adjust as necessary.
Realistically, a much simpler query is along the lines of what Gordon has suggested:
SELECT Total = ISNULL(CONVERT(VARCHAR(20), Customer), 'Total'),
AUD = SUM(CASE WHEN Currency = 'AUD' THEN Balances END),
CAD = SUM(CASE WHEN Currency = 'CAD' THEN Balances END),
EUR = SUM(CASE WHEN Currency = 'EUR' THEN Balances END),
GBP = SUM(CASE WHEN Currency = 'GBP' THEN Balances END),
RowTotal = SUM(Balances)
FROM #temptable
GROUP BY Customer WITH ROLLUP;
Upvotes: 1
Reputation: 1269833
Just use aggregation:
SELECT SUM(CASE WHEN Currency = 'AUD' THEN Balance ELSE 0 END) as aud,
SUM(CASE WHEN Currency = 'CAD' THEN Balance ELSE 0 END) as cad,
SUM(CASE WHEN Currency = 'EUR' THEN Balance ELSE 0 END) as eur,
SUM(CASE WHEN Currency = 'GBP' THEN Balance ELSE 0 END) as gbp
FROM #temptable;
If you can live with one row per currency, GROUP BY
is simpler:
select currency, sum(balance)
from #temptable
group by currency;
Upvotes: 0