Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Server 2008 Reporting: Sum of Max of group

I have a table like this in the report designer:

Category:       1     2       3      4   Total
Max Amount:     x     y       z      c     ?

I need to get the total of Max Amount, but expressions will not let me take Sum(Max(amount)), and the add total is disabled for this cell.

The max amount row is an expression that takes the max of each category. The source data has repeated values, so I just take the max. For example:

Category    Amount
    1         4.6
    1         4.6
    1         4.6
    2          5
    3          4

Other columns in the table are different, but amount will be the same so I cannot only select distinct values.

like image 580
richsoni Avatar asked Apr 19 '12 14:04

richsoni


People also ask

How do I SUM the number of groups in SQL?

If you need to add a group of numbers in your table you can use the SUM function in SQL. This is the basic syntax: SELECT SUM(column_name) FROM table_name; If you need to arrange the data into groups, then you can use the GROUP BY clause.

Can we use SUM with GROUP BY?

SUM is used with a GROUP BY clause. The aggregate functions summarize the table data. Once the rows are divided into groups, the aggregate functions are applied in order to return just one value per group. It is better to identify each summary row by including the GROUP BY clause in the query resulst.

Can I use SUM and Max in same query?

SUM() and MAX() at the same time Notice that all aggregate functions except COUNT(*) ignore the NULL Rating for the ID=5 row. COUNT(*) counts rows, whereas COUNT(col) counts non-null values. So to answer your question, just go ahead and use SUM() and MAX() in the same query.

What does SUM () return in SQL?

The SUM() function returns the total sum of a numeric column.


2 Answers

Maybe something like this:

SELECT
    SUM(t1.maxAmout)
FROM
(
    SELECT
        MAX(t.Amout) AS maxAmout,
        t.Category
    FROM
        yourTable AS t
    GROUP BY
        t.Category
) AS t1

You can also do it like this. If you are using sql server 2005+:

SELECT
    pvt.[1],
    pvt.[2],
    pvt.[3],
    (
        pvt.[1]+
        pvt.[2]+
        pvt.[3]
    ) AS Total
FROM
(
    SELECT
        t.Category,
        t.Amout
    FROM
        yourTable AS t
) AS SourceTable
PIVOT
(
    MAX(Amout)
    FOR Category IN([1],[2],[3])
) AS pvt

EDIT

If you have a 1000 categories. Then a dynamic pivot would be the best solution. So like this:

Test data

CREATE TABLE #T
    (
        Category INT,
        Amout FLOAT
    )

INSERT INTO #T
VALUES
    (1,4.6),
    (1,4.6),
    (1,4.6),
    (2,5),
    (3,4)

Unique column names

DECLARE @cols VARCHAR(MAX)
DECLARE @colsTotal VARCHAR(MAX)
;WITH CTE
AS
(
    SELECT
        ROW_NUMBER() OVER(PARTITION BY t.Category ORDER BY t.Amout) AS RowNbr,
        t.*
    FROM
        #T AS t
)
SELECT  @cols = COALESCE(@cols + ','+QUOTENAME(Category),
                     QUOTENAME(Category)),
        @colsTotal=COALESCE(@colsTotal + '+ISNULL('+QUOTENAME(Category)+',0)',
                     'ISNULL('+QUOTENAME(Category)+',0)')
FROM 
    CTE
WHERE
    CTE.RowNbr=1
ORDER BY 
    Category

Dynamic pivot

DECLARE @query NVARCHAR(4000)=
N'SELECT
    '+@cols+',
    (
        '+@colsTotal+'
    ) AS Total
FROM
(
    SELECT
        t.Category,
        t.Amout
    FROM
        #T AS t
) AS SourceTable
PIVOT
(
    MAX(Amout)
    FOR Category IN('+@cols+')
) AS pvt'

EXECUTE(@query)
like image 183
Arion Avatar answered Oct 12 '22 23:10

Arion


WITH
  aggregate
AS
(
  SELECT
    category,
    MAX(amount)  AS max_amount
  FROM
    yourTable
  GROUP BY
    category
)
SELECT
  MAX(CASE WHEN category = 1 THEN max_amount ELSE NULL END)    AS [1],
  MAX(CASE WHEN category = 2 THEN max_amount ELSE NULL END)    AS [2],
  MAX(CASE WHEN category = 3 THEN max_amount ELSE NULL END)    AS [3],
  MAX(CASE WHEN category = 4 THEN max_amount ELSE NULL END)    AS [4],
  SUM(max_amount)                                              AS [total]
FROM
  aggregate
like image 39
MatBailie Avatar answered Oct 12 '22 22:10

MatBailie