Subtotals and SQL
I have a SQL table of sales data (like the one below), how can I generate a result set that inlines the subtotals and idealy sorts the results in descending order of the highest paying customer?
So given a table like the following:
CUS_ID | PRODUCT | AMOUNT
12 | A | 2.50
12 | B | 5.80
24 | A | 10.00
24 | B | 30.00
I would get the following result:
CUS_ID | Product | AMOUNT
24 | A | 10.00
24 | B | 30.00
24 | Total 开发者_运维知识库 | 30.00
12 | A | 2.50
12 | B | 5.00
12 | Total | 7.50
So far, I can come with the following query:
SELECT cus_id, product, amount FROM Sales
UNION ALL
(SELECT cus_id, 'ZZZZ' AS product, SUM(amount) FROM Sales GROUP BY cus_id)
ORDER BY cus_id, product
However, the query uses 'ZZZZ' instead of 'Total' (which can be fixed by find-and-replace afterwards), but it doesn't sort in order of amount.
EDIT: Please feel free to post answers that don't address sorting. Some of the answers were actually pretty helpful to me.
Have a look at something like
DECLARE @Sales TABLE(
CUS_ID INT,
PRODUCT VARCHAR(20),
AMOUNT FLOAT
)
INSERT INTO @Sales SELECT 12,'A', 2.50
INSERT INTO @Sales SELECT 12,'B', 5.80
INSERT INTO @Sales SELECT 24,'A', 10.00
INSERT INTO @Sales SELECT 24,'B', 30.00
;WITH Vals AS (
SELECT cus_id,
product,
amount,
1 DisplayOrder,
SUM(amount) OVER(PARTITION BY cus_id) OrderTotal
FROM @Sales
UNION ALL
SELECT cus_id,
'Total' AS product,
SUM(amount),
2 DisplayOrder,
SUM(amount)
FROM @Sales
GROUP BY cus_id
)
SELECT cus_id,
product,
amount
FROM Vals
ORDER BY OrderTotal DESC,cus_id,DisplayOrder, product
As you are happy to not have sorting here is a quick response before i get back to work. There is a fantastic reporting feature in Sql server - With Rollup. It adds subtotal and total lines to a query automagically; based on the groupings you are using.
As a very quick example using @astander's table definition
DECLARE @Sales TABLE(
CUS_ID INT,
PRODUCT VARCHAR(20),
AMOUNT FLOAT
)
INSERT INTO @Sales SELECT 12,'A', 2.50
INSERT INTO @Sales SELECT 12,'B', 5.80
INSERT INTO @Sales SELECT 24,'A', 10.00
INSERT INTO @Sales SELECT 24,'B', 30.00
Select Cus_ID, Product, SUM(Amount)
From @Sales
group by cus_id, product with rollup
This returns
Cus_ID Product
----------- -------------------- ----------------------
12 A 2.5
12 B 5.8
12 NULL 8.3
24 A 10
24 B 30
24 NULL 40
NULL NULL 48.3
To make it easier to write your reporting data extract and identify the subtotal rows there is a function - grouping - which you can query by group by elements. In the example below it identifies subtotal and total lines.
DECLARE @Sales TABLE(
CUS_ID INT,
PRODUCT VARCHAR(20),
AMOUNT FLOAT
)
INSERT INTO @Sales SELECT 12,'A', 2.50
INSERT INTO @Sales SELECT 12,'B', 5.80
INSERT INTO @Sales SELECT 24,'A', 10.00
INSERT INTO @Sales SELECT 24,'B', 30.00
select
case
when GROUPING(product) = 1 and GROUPING(cus_id) = 0 then 'Sub Total - Customer -' + cast(Cus_ID as varchar(10))
when GROUPING(product) = 1 and GROUPING(cus_id) = 1 then 'Total'
else cast(Cus_ID as varchar(10)) end as Cus_ID,
PRODUCT,
sum(Amount) as Total_Amount
From @sales
group by cus_id, product with rollup
Returning
Cus_ID PRODUCT Total_Amount
-------------------------------- -------------------- ----------------------
12 A 2.5
12 B 5.8
Sub Total - Customer -12 NULL 8.3
24 A 10
24 B 30
Sub Total - Customer -24 NULL 40
Total NULL 48.3
A slight tweak will get it to do the sorting you are after.
精彩评论