2013-03-04 57 views
0

複雜aggregration視圖我如何複雜aggregration視圖如何

有一個表(Table A)與[payment type][Agent],[Amount Credit][Amount Debit]。現在我正在尋找這個數據的特定視圖。

我希望爲每個代理商提供他/她的活動摘要。

So代理沿x軸支付類型沿y軸與每個代理商的彙總以及。

Transaction type  Agent 1 Agent 2 

Amount Credit     

Cash    20 40 
Credit Card   20 20 

Total    40 60 

Amount Debit     

Cash    20 40 
Credit Card   10 10 

Total    30 50 

試了一下,不能得到這個視圖呢。

+1

你可能想發佈的東西你已經嘗試過呢。 – 2013-03-04 14:04:52

+0

如果代理人數量隨時間而變化,則無法將其作爲視圖編寫。 SQL不是電子表格系統。查詢產生的列數(及其類型和名稱)是固定的。 – 2013-03-04 14:05:44

回答

2

您可以通過應用UNPIVOTPIVOT函數來獲得所需的結果。如果你有一個已知數量要轉換成列agent值,那麼你可以硬編碼查詢:

select 
    case when TransactionType is null then 'Total' else [Credit/Debit] end [Credit/Debit], 
    case when TransactionType is null then '' else TransactionType end TransactionType, 
    Sum([Agent 1]) Agent1, 
    sum([Agent 2]) Agent2 
from 
(
    select [Agent], 
    [Credit/Debit], 
    PaymentType as TransactionType, 
    value 
    from TableA 
    unpivot 
    (
    value 
    for [Credit/Debit] in ([AmountCredit], [AmountDebit]) 
) unpiv 
) src 
pivot 
(
    sum(value) 
    for agent in ([Agent 1], [Agent 2]) 
) piv 
group by GROUPING SETS ([Credit/Debit], TransactionType), ([Credit/Debit]); 

SQL Fiddle with Demo

如果您有一個未知數量的agents,那麼您將需要使用動態SQL,但不能在視圖中使用動態SQL,您必須將代碼放入存儲過程中。動態SQL將爲:

DECLARE @cols AS NVARCHAR(MAX), 
    @colSum AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Agent) 
        from TableA 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

select @colSum = STUFF((SELECT distinct ', Sum(' + QUOTENAME(Agent)+') as ' +QUOTENAME(Agent) 
        from TableA 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'select 
       case when TransactionType is null then ''Total'' else [Credit/Debit] end [Credit/Debit], 
       case when TransactionType is null then '''' else TransactionType end TransactionType, 
       '[email protected] +' 
       from 
       (
       select [Agent], 
        [Credit/Debit], 
        PaymentType as TransactionType, 
        value 
       from TableA 
       unpivot 
       (
        value 
        for [Credit/Debit] in ([AmountCredit], [AmountDebit]) 
       ) unpiv 
      ) src 
       pivot 
       (
       sum(value) 
       for agent in ('[email protected]+') 
      ) piv 
       group by GROUPING SETS ([Credit/Debit], TransactionType), ([Credit/Debit])' 

execute(@query) 

請參閱SQL Fiddle with Demo。查詢的結果將是:

| CREDIT/DEBIT | TRANSACTIONTYPE | AGENT 1 | AGENT 2 | 
------------------------------------------------------ 
| AmountCredit |   Cash |  20 |  40 | 
| AmountCredit |  Credit Card |  20 |  20 | 
|  Total |     |  40 |  60 | 
| AmountDebit |   Cash |  20 |  40 | 
| AmountDebit |  Credit Card |  10 |  10 | 
|  Total |     |  30 |  50 | 
+0

+1這是一個很好的答案 - 涵蓋了所有內容 - 幾乎試圖刪除我的嘗試! – whytheq 2013-03-04 14:52:32

1

聽起來你正在試圖做類似PIVOT

CREATE TABLE #Table 
(
    [PayType] VARCHAR(100), 
    [Name] VARCHAR(100), 
    [Amt1] INT, 
    [Amt2] INT 
) 

INSERT INTO #Table VALUES 
('Cash','michaeljackson',1,9), 
('Credit','michaeljackson',1,9), 
('Cash','jq',10,20), 
('Credit','jq',7,9), 
('Cash','phil',1,2), 
('Credit','phil',3,4), 
('Cash','simplesimon',99,1), 
('Credit','simplesimon',101,2); 


SELECT * 
FROM 
    ( 
    SELECT PayType, 
     Name, 
     Amt1 
    FROM #Table 
    ) AS sourceTable 
    PIVOT 
    (
    SUM(Amt1) FOR Name IN ("michaeljackson","jq","phil", "simplesimon") 
    ) AS pivotTable; 

SELECT * 
FROM 
    ( 
    SELECT PayType, 
     Name, 
     Amt2 
    FROM #Table 
    ) AS sourceTable 
    PIVOT 
    (
    SUM(Amt2) FOR Name IN ("michaeljackson","jq","phil", "simplesimon") 
    ) AS pivotTable;