复合聚合视图如何

时间:2013-03-04 13:44:08

标签: sql sql-server pivot unpivot

复杂聚合视图如何

我有Table A[payment type][Agent],[Amount Credit]的表格([Amount Debit])。现在我正在寻找这个数据的特定视图。

我希望EACH代理人了解他/她的活动摘要。

沿着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 

尝试了一切,但却无法得到这个观点。

2 个答案:

答案 0 :(得分: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,
                '+@colSum +'
              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 ('+@cols+')
              ) 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 |

答案 1 :(得分: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;