0

复杂的聚合视图如何

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

我想为每个代理提供他/她的活动摘要。

因此,代理沿 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 

尝试了一切,但还没有得到这个视图。

4

2 回答 2

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 |
于 2013-03-04T14:41:21.087 回答
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;
于 2013-03-04T14:51:50.690 回答