用于将列转置为行的SQL查询

时间:2014-12-22 20:01:40

标签: tsql pivot

有人可以帮助查询以下问题

退货表

Id     Factor  monthlyReturns  price date

A1     0.2     0.001           2010-01-29
A1     0.2     0.003           2010-02-26
A1     0.2     0.004           2010-03-31
A1     0.2     0.004           2010-04-30
A2     0.1     0.001           2010-01-29
A2     0.1     0.001           2010-02-26
A2     0.1     0.001           2010-03-31
A2     0.1     0.001           2010-04-30 
A3     0.3     0.03            2010-01-29 
A3     0.3     0.04            2010-02-26
A3     0.3     0.05            2010-03-31
A3     0.3     0.05            2010-04-30
A4     0.4     0.12            2010-01-29
A4     0.4     0.12            2010-02-26
A4     0.4     0.14            2010-03-31
A4     0.4     0.15            2010-04-30

我想将此数据转换为以下格式。有人请建议查询

            A1       A2      A3      A4      Total
31-Jan-10   0.001   0.001   0.03    0.12     0.001*0.2(Factor for  A1)+0.001*0.1(Factor forA2)+
                                             0.03*0.3(Factor forA3)+ 0.12*0.4(Factor forA4)

28-Feb-10   0.003   0.001   0.04    0.12     Same as above
31-Mar-10   0.004   0.001   0.05    0.14     Same as above
30-Apr-10   0.004   0.001   0.05    0.15     Same as above

由于

1 个答案:

答案 0 :(得分:1)

下面是您要求的查询,请注意您需要将表名更改为您的。

一点解释: 我认为Ids仅限于A1,A2,A3,A4。否则这将不起作用,你需要一个更复杂的解决方案。

首先我创建了一个透视表的公用表表达式,其中所有因子都按日期分组(假设在同一日期不能有两个因素同一个id)

然后,我加入了一个包含所有月回报的数据透视表。

注意:我在字段A1,A2,...上使用了sum函数,因为我需要按日期对其进行分组,如果列不在group by子句中,则select只能使用聚合函数。 这不会影响这些值,因为在特定日期每个id只有一行,但如果我错了,请纠正我。

with FactorsByDate(PriceDate,FactorA1,FactorA2,FactorA3,FactorA4)
AS
(
  SELECT [price date] AS Date, 
  SUM([A1]) AS A1, SUM([A2]) AS A2, SUM([A3]) AS A3, SUM([A4]) AS A4
  FROM
  (SELECT Id, Factor , [price date]
   FROM TempTbl) AS SourceTable
   PIVOT
   (
     SUM(Factor)
     FOR Id IN ([A1], [A2], [A3], [A4])
   ) AS PivotTable
   group by [price date]
)
SELECT Date,A1,A2,A3,A4, A1*FactorA1 + A2*FactorA2 + A3*FactorA3 + A4*FactorA4 AS Total
FROM
(
  SELECT [price date] AS Date, 
  SUM([A1]) AS A1, SUM([A2]) AS A2, SUM([A3]) AS A3, SUM([A4]) AS A4
  FROM
  (SELECT Id, monthlyReturns , [price date]
   FROM TempTbl) AS SourceTable
   PIVOT
   (
     SUM(monthlyReturns)
     FOR Id IN ([A1], [A2], [A3], [A4])
   ) AS PivotTable
   group by [price date]
  ) AS monthlyReturns
INNER JOIN FactorsByDate ON FactorsByDate.PriceDate = monthlyReturns.Date