2012-04-19 20 views
7

Tengo una tabla de este tipo en el diseñador de informes:SQL Server 2008 Reporting: Suma de Max del grupo

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

necesito para obtener el total de Max Cantidad, sino expresiones no me deja tomo Sum (Max (cantidad)), y el total agregado está deshabilitado para esta celda.

La fila de cantidad máxima es una expresión que toma el máximo de cada categoría. La fuente de datos tiene valores repetidos, así que solo tomo el máximo. Por ejemplo:

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

Otras columnas de la tabla son diferentes, pero la cantidad será el mismo por lo que no sólo se pueden seleccionar valores distintos.

+0

¿Qué versión de SQL está utilizando? – Arion

+0

Estoy usando 2008 – richsoni

Respuesta

9

Tal vez algo como esto:

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

También puede hacerlo de esta manera. Si está utilizando 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 

EDITAR

Si usted tiene un 1000 categorías. Entonces, un pivote dinámico sería la mejor solución. Así como esto:

Los datos de prueba

CREATE TABLE #T 
    (
     Category INT, 
     Amout FLOAT 
    ) 

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

nombres de columna únicos

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 

cruzada dinámica

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

EXECUTE(@query) 
+0

¿y si hay 1000 categorías? sólo curiosidad si esta es la mejor solución – dansasu11

+0

@paabobo: si hay 1000 categoría todavía haría un pivote. Pero en ese caso un pivote dinámico. Si es la mejor solución o no. Todo depende del esquema de la base de datos. Pero en el lado positivo es que solo tienes que agrupar por unos. Eso tiene que ser mucho más rápido. Creo que en este caso un pivote puede ser positivo para el rendimiento. – Arion

+0

@rsoni: Recuerda votar la respuesta que creas que es buena. Eso nos da a todos una cálida sensación borrosa: P – Arion

2
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 
0

Los siguientes devuelve un solo valor:

SELECT DISTINCT SUM(MAX(Amount)) OVER() 
FROM atable 
GROUP BY Category 

Usted podría utilizar esto como una sub consulta calcular el valor de la columna de Total.

Alternativamente, TOP (1) podrían utilizarse en lugar de DISTINCT (no sé por qué no podía pensar en él antes):

SELECT TOP (1) SUM(MAX(Amount)) OVER() 
FROM atable 
GROUP BY Category 
Cuestiones relacionadas