开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜