sql 服务器中的多枢轴

Multi pivot in sql server

以下是我的 sql 服务器的查询:

     SELECT t.type ,
        t.fmsales ,
        t.indussales 
 FROM   ( SELECT    CASE WHEN ( GROUPING(mti.type) = 1 ) THEN 'ALL'
                         ELSE ISNULL(mti.Type, 'UNKNOWN')
                    END AS type ,
                    SUM(ISNULL(mti.SALES_THIS + mti.SWITCHIN_THIS, 0)) fmsales ,
                    SUM(ISNULL(mti.SALES_ALL + mti.SWITCHIN_ALL, 0)) indussales 

          FROM      dbo.IMonthly_trigger_Industry mti ,
                    dbo.RMMappingDb rm ,
                    dbo.EmployeeDB ed
          WHERE     ed.EmployeeCode = 1217
                    AND rm.BranchName = mti.Branch
                    AND rm.ARNCode = mti.BROKER
                    AND rm.EmployeeCode = ed.EmployeeCode
                    AND mti.BROKER_NAME LIKE '%Pvt Limited%'
          GROUP BY  mti.Type
                    WITH CUBE
        ) t
 WHERE  t.type IS NOT NULL
 GROUP BY t.type ,
        t.fmsales ,
        t.indussales;

结果是这样的:

我想转置这个结果集,使行变成列,列变成行。我之前使用了 pivot 方法,其中我只有一列来进行聚合,但这里是不同的。有人可以帮助我实现这一目标吗?

结果应该是这样的:

我怎样才能做到这一点?我尝试使用数据透视表,因为数据透视表只允许在一列上进行聚合,所以我无法获得预期的结果。任何帮助深表感谢。提前致谢。

您可以使用 PIVOTUNPIVOT 的组合来执行此操作,如下所示:

select * 
from
  (
      select * from t
  ) s
unpivot
  (
    val for product in ([fmsales],[indussales])
  )up
pivot
  (
    max(val) for type in ([ALL],[CASH],[DEBIT],[EQUITY])
   )p

演示 sql fiddle link:http://sqlfiddle.com/#!6/381f7/4

解释:

首先,我们使用 UNPIVOT 获取 fmsalesindussales 列名作为行数据,然后 PIVOT 覆盖 type 列。 在此处查看 UNPIVOT 的中间结果:

http://sqlfiddle.com/#!6/381f7/5

您可以使用 UNION ALL 首先对数据进行逆透视,然后使用条件聚合进行透视:

WITH Cte AS(
    --Your original query here
    SELECT 'ALL' AS type, 0 AS fmsales, 82.1 AS indussales UNION ALL
    SELECT 'CASH' AS type, 0 AS fmsales, 0 AS indussales UNION ALL
    SELECT 'DEBT' AS type, 0 AS fmsales, 62 AS indussales UNION ALL
    SELECT 'EQUITY' AS type, 0 AS fmsales, 20.1 AS indussales
),
CteUnpivot AS(
    SELECT 'fmsales' AS products, 'ALL' AS type, fmsales AS val FROM Cte WHERE type = 'ALL' UNION ALL
    SELECT 'fmsales' AS products, 'CASH' AS type, fmsales AS val FROM Cte WHERE type = 'CASH' UNION ALL
    SELECT 'fmsales' AS products, 'DEBT' AS type, fmsales AS val FROM Cte WHERE type = 'DEBT' UNION ALL
    SELECT 'fmsales' AS products, 'EQUITY' AS type, fmsales AS val FROM Cte WHERE type = 'EQUITY'UNION ALL
    SELECT 'indussales' AS products, 'ALL' AS type, indussales AS val FROM Cte WHERE type = 'ALL' UNION ALL
    SELECT 'indussales' AS products, 'CASH' AS type, indussales AS val FROM Cte WHERE type = 'CASH' UNION ALL
    SELECT 'indussales' AS products, 'DEBT' AS type, indussales AS val FROM Cte WHERE type = 'DEBT' UNION ALL
    SELECT 'indussales' AS products, 'EQUITY' AS type, indussales AS val FROM Cte WHERE type = 'EQUITY'
)
SELECT
    [ALL] = SUM(CASE WHEN type = 'ALL' THEN val ELSE 0 END),
    CASH = SUM(CASE WHEN type = 'CASH' THEN val ELSE 0 END),
    DEBT = SUM(CASE WHEN type = 'DEBT' THEN val ELSE 0 END),
    EQUITY = SUM(CASE WHEN type = 'EQUITY' THEN val ELSE 0 END)
FROM CteUnpivot
GROUP BY products

当首先 unpivoting 数据然后 pivoting 结果时,您可以通过标准技巧做到这一点:

DECLARE @t TABLE(type NVARCHAR(MAX), fmsales MONEY, indussales MONEY)

INSERT INTO @t VALUES
('ALL', 0, 82.1),
('CASH', 0, 0),
('DEBT', 0, 62),
('EQUITY', 0, 20.1)


SELECT * FROM @t
UNPIVOT(a FOR products IN([fmsales],[indussales]))u
PIVOT (MAX(a) FOR type IN([ALL],[CASH],[DEBT],[EQUITY]))p

输出:

products    ALL     CASH    DEBT    EQUITY
fmsales     0.00    0.00    0.00    0.00
indussales  82.10   0.00    62.00   20.10

为了将此应用于您的查询,您可以使用 common table expressions(CTE),例如:

;WITH cte AS(
             SELECT t.type ,
                    t.fmsales ,
                    t.indussales
             FROM   ( SELECT    CASE WHEN ( GROUPING(mti.type) = 1 ) THEN 'ALL'
                                     ELSE ISNULL(mti.Type, 'UNKNOWN')
                                END AS type ,
                                SUM(ISNULL(mti.SALES_THIS + mti.SWITCHIN_THIS, 0)) fmsales ,
                                SUM(ISNULL(mti.SALES_ALL + mti.SWITCHIN_ALL, 0)) indussales
                      FROM      dbo.IMonthly_trigger_Industry mti ,
                                dbo.RMMappingDb rm ,
                                dbo.EmployeeDB ed
                      WHERE     ed.EmployeeCode = 1217
                                AND rm.BranchName = mti.Branch
                                AND rm.ARNCode = mti.BROKER
                                AND rm.EmployeeCode = ed.EmployeeCode
                                AND mti.BROKER_NAME LIKE '%Pvt Limited%'
                      GROUP BY  mti.Type
                                WITH CUBE
                    ) t
             WHERE  t.type IS NOT NULL
             GROUP BY t.type ,
                    t.fmsales ,
                    t.indussales
        )
SELECT * FROM cte
UNPIVOT(a FOR products IN([fmsales],[indussales]))u
PIVOT (MAX(a) FOR type IN([ALL],[CASH],[DEBT],[EQUITY]))p

我们可以在交叉应用中完成,但已经晚了

DECLARE @t TABLE(type NVARCHAR(MAX), fmsales MONEY, indussales MONEY)

    INSERT INTO @t VALUES
    ('ALL', 0, 82.1),
    ('CASH', 0, 0),
    ('DEBT', 0, 62),
    ('EQUITY', 0, 20.1)

    select  col As Products,[ALL],[Cash],[Debt],[Equity],
    from (select type,col,val from @t

    CROSS APPLY (values(fmsales, 'fmsales'),( indussales, 'indussales'))CS(col,val))K

    PIVOT(MAX(val)
    FOR TYPE IN
     ([ALL],[Cash],[Debt],[Equity]))P