2012-04-19 40 views
7

Tôi có một bảng như thế này trong nhà thiết kế báo cáo:SQL Server 2008 Reporting: Sum của Max của nhóm

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

tôi cần phải nhận được tổng cộng Max Số tiền, nhưng biểu hiện sẽ không cho phép tôi đưa Sum (Max (số tiền)), và tổng cộng thêm bị vô hiệu hóa cho ô này.

Hàng số tiền tối đa là biểu thức nhận tối đa của từng danh mục. Dữ liệu nguồn có giá trị lặp lại, vì vậy tôi chỉ lấy tối đa. Ví dụ:

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

Các cột khác trong bảng khác nhau, nhưng số tiền sẽ giống nhau nên tôi không thể chỉ chọn các giá trị riêng biệt.

+0

phiên bản sql gì bạn đang sử dụng? – Arion

+0

Tôi đang sử dụng 2008 – richsoni

Trả lời

9

Có lẽ một cái gì đó như thế này:

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

Bạn cũng có thể làm điều đó như thế này. Nếu bạn đang sử dụng 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

Nếu bạn có 1000 loại. Sau đó, một trục động lực sẽ là giải pháp tốt nhất. Vì vậy, như thế này:

dữ liệu thử nghiệm

CREATE TABLE #T 
    (
     Category INT, 
     Amout FLOAT 
    ) 

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

tên cột Unique

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 

động trục

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

nếu có 1000 danh mục thì sao? chỉ tò mò nếu đây là giải pháp tốt nhất – dansasu11

+0

@paabobo: nếu có 1000 danh mục vẫn sẽ làm một trục. Nhưng trong trường hợp đó, một trục động. Nếu đó là giải pháp tốt nhất hay không. Tất cả phụ thuộc vào lược đồ cơ sở dữ liệu. Nhưng về mặt tích cực là bạn chỉ phải nhóm theo từng người. Đó phải là hiệu suất vise nhanh hơn nhiều. Tôi nghĩ trong trường hợp này, một trục có thể tích cực cho hiệu suất. – Arion

+0

@ rsoni: Hãy nhớ để upvote câu trả lời bạn nghĩ là tốt. Điều đó mang lại cho chúng ta tất cả cảm giác mờ ấm: 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

Lợi nhuận sau một giá trị duy nhất:

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

Bạn có thể sử dụng như một subquery tính giá trị của cột Total.

Ngoài ra, TOP (1) có thể được sử dụng thay cho DISTINCT (không biết tại sao tôi không thể nghĩ về nó trước đó):

SELECT TOP (1) SUM(MAX(Amount)) OVER() 
FROM atable 
GROUP BY Category 
Các vấn đề liên quan