I have the following data in which I would like to unpivot
I created this query to unpivot the 'Actual' rows but can't seem to figure out the syntax for unpivoting the 'Plan' and 'PriorYear' as well.
SELECT FiscalYear, Period, MetricName, ActualValue
FROM vw_ExecSummary
UNPIVOT
(ActualValue FOR MetricName IN ( [Net Revenue], [Total C.S. Salaries]
)) AS unpvt
WHERE [Type] = 'Actual'
The unpivoted data looks like this but I want to also add the Plan and PriorYear columns to the right of the ActualValue column below
Any help would be greatly appreciated. Thanks.
I can't test this at the moment, but I think it works like this. First, you need to UNPIVOT
all the data:
SELECT fiscalYear, period, type, metricName, metricValue
FROM vw_ExecSummary
UNPIVOT (metricValue FOR metricName IN ([Net Revenue], [Total C.S. Salaries])) unpvt
Which should result in a table that looks something like this:
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)
We could then PIVOT
the rows as normal to get the new columns (that's what it's for):
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
(the SUM(...)
shouldn't actually do anything here, as presumable the other columns comprise a unique row, but we're required to use an aggregate function)
...which should yield something akin to the following:
fiscalYear period metricName actualValue planValue priorYearValue
======================================================================================
15 1 'Net Revenue' 3676798.98999997 3503920.077405 40436344.4499999
...................................... (remaining rows omitted)
So putting it together would look like this:
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
I have just one concern, though: values like 3676798.98999997
, 3503920.077405
, etc, make me think those columns are floating point (ie, REAL
or FLOAT
),but the values are named for monetary uses. If this is the case.... you are aware floating-point values can't store things like .1
exactly, right (ie, you can't actually add a dime to a value)? And that, when values get large enough, you can't add 1
anymore either? Usually when dealing with monetary values you should be using something based on a fixed-point type, like DECIMAL
or NUMERIC
.