2014-07-18 23 views
0

我有,我想UNPIVOT逆透视数据与多列 - 语法帮助请

enter image description here

我创造了这个查询UNPIVOT的“实际”行,但似乎无法以下数据找出未计划'计划'和'优先'的语法。

SELECT FiscalYear, Period, MetricName, ActualValue 
FROM vw_ExecSummary 
UNPIVOT 
(ActualValue FOR MetricName IN ([Net Revenue], [Total C.S. Salaries] 
)) AS unpvt 
WHERE [Type] = 'Actual' 

逆转置数据看起来是这样,但我想还计划和PriorYear列添加到ActualValue栏的右侧下方

enter image description here

任何帮助将不胜感激。谢谢。

回答

1

我目前无法测试此功能,但我认为它可以像这样工作。首先,你需要UNPIVOT所有数据:

SELECT fiscalYear, period, type, metricName, metricValue 
FROM vw_ExecSummary 
UNPIVOT (metricValue FOR metricName IN ([Net Revenue], [Total C.S. Salaries])) unpvt 

应该产生看起来是这样的一个表,该表:

fiscalYear period type  metricName    metricValue 
=================================================================== 
15   1  'Actual' 'Net Revenue'   3676798.98999997 
15   1  'Actual' 'Total C.S. Salaries' 1463044.72 
15   1  'Plan' 'Net Revenue'   3503920.077405 
...................... (remaining rows omitted) 

然后我们可以PIVOT行正常,以获得新的列(这就是它的用途):

SELECT fiscalYear, period, metricName, 
     [Actual] AS actualValue, [Plan] AS planValue, [PriorYear] AS priorYearValue 
FROM <previous_data> 
PIVOT (SUM(metricValue) FOR (type IN ([Actual], [Plan], [PriorYear]) pvt 

SUM(...)实际上不应该做一个ything这里,作为推测其他列包含唯一行,但我们需要使用聚合函数)

...这应该产生一个类似于如下:

fiscalYear period metricName  actualValue  planValue  priorYearValue 
====================================================================================== 
15   1  'Net Revenue' 3676798.98999997 3503920.077405 40436344.4499999 
...................................... (remaining rows omitted) 

所以把它在一起应该是这样的:

SELECT fiscalYear, period, metricName, 
     [Actual] AS actualValue, [Plan] AS planValue, [PriorYear] AS priorYearValue 
FROM (SELECT fiscalYear, period, type, metricName, metricValue 
     FROM vw_ExecSummary 
     UNPIVOT (metricValue FOR metricName IN ([Net Revenue], [Total C.S. Salaries])) unpvt) unpvt 
PIVOT (SUM(metricValue) FOR type IN ([Actual], [Plan], [PriorYear])) AS pvt 

SQL Fiddle Example


我只有一个顾虑,但:值一样3676798.989999973503920.077405等,让我觉得那些列浮点(即REALFLOAT),但值被命名为货币用途。如果是这种情况....你知道浮点值不能正确地存储像.1的东西,正确(即,你实际上不能添加一个角钱的价值)?而且,当数值变得足够大时,您不能再添加1?通常在处理货币价值时,您应该使用基于定点类型的东西,如DECIMALNUMERIC

+0

感谢,该解决方案 - 当场上!我没有注意到在PIVOT语句中的'type'这个单词不正确之前的括号。我删除了它,并在PIVOT声明的末尾添加了一个右括号。像魅力一样工作! – Jason

+0

@Jason - 啊,谢谢。 #更正#。这就是为什么我喜欢先测试它们。那么,这两种金钱列的类型是什么? –

+0

我相信这种类型是浮动的(目前不在我工作的笔记本电脑前)。 – Jason

0

这是Itzig Ben-Gan's cross apply values pivoting一种情况:

create table #data (FiscalYear smallint, Period tinyint, ValueType nvarchar(25), NetRevenue float, Salaries float); 
insert into #data values 
    (15,1,N'Actual',3676798.98999,1463044.71999), 
    (15,1,N'Plan',3503920.977405,1335397.32878), 
    (15,1,N'PriorYear',4043634.449,1543866.89); 

select d.FiscalYear, d.Period, 
     ActualNetRevenue = sum(v.ActualNetRevenue), ActualSalaries = sum(v.ActualSalaries), 
     PlanNetRevenue = sum(v.PlanNetRevenue), PlanSalaries = sum(v.PlanSalaries), 
     PriorYearNetRevenue = sum(v.PriorYearNetRevenue), PriorYearSalaries = sum(v.PriorYearSalaries) 
from #data d 
cross apply 
     (values 
     (N'Actual',d.NetRevenue,d.Salaries,0,0,0,0), 
     (N'Plan',0,0,d.NetRevenue,d.Salaries,0,0), 
     (N'PriorYear',0,0,0,0,d.NetRevenue,d.Salaries)) 
     v (ValueType, ActualNetRevenue, ActualSalaries, PlanNetRevenue, PlanSalaries, PriorYearNetRevenue, PriorYearSalaries) 
where d.ValueType = v.ValueType 
group by d.FiscalYear, d.Period; 

drop table #data; 
+0

谢谢,但本例将所有项目放在一行中。上面的解决方案就是我打算做的。 – Jason