【问题标题】:Complex aggregration view how to复杂聚合视图如何
【发布时间】:2013-03-04 13:44:08
【问题描述】:

复杂的聚合视图如何

我有一张桌子 (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 

尝试了所有方法,但仍无法获得此视图。

【问题讨论】:

  • 你可能想发布你已经尝试过的东西。
  • 如果代理的数量会随时间变化,则无法将其写为视图。 SQL 不是电子表格系统。查询产生的列数(及其类型和名称)是固定的。

标签: sql sql-server pivot unpivot


【解决方案1】:

您可以通过同时应用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 这是一个很好的答案-涵盖了所有内容-几乎想删除我的尝试!
【解决方案2】:

听起来你正在尝试做类似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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-11-04
    • 2012-06-09
    • 2019-03-14
    • 2014-10-21
    • 2017-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多