This seems like it should be a common need, but I'm not seeing how to do this using T-SQL PIVOT function. Specifically, I want to calculate the AVG and STDEV for a column over a Pivot column value. The data look something like this (lots of data omitted, but this gets to the heart):
--------------------------------------------------------------------------
ID Year PersonID Score
--------------------------------------------------------------------------
106 2001 1 20
107 2002 1 30
108 2003 1 40
109 2004 1 50
106 2002 2 20
107 2003 2 50
108 2004 2 30
109 2005 2 10
--------------------------------------------------------------------------
I would like to see the following output
--------------------------------------------------------------------------
NonPivotCol1 NonPivotCol2 2001_Mean 2001_Avg 2002_Mean 2002_Avg Etc
--------------------------------------------------------------------------
Some Value Some Value 32 5.2 28 3.1
Etc.
--------------------------------------------------------------------------
Do I need to revert to the old CASE statement logic?
Thanks!
4 Answers. It is a common question to get the output of at least two aggregate functions in the SQL pivot table columns. Of course it is not possible to combine two different values resulting from two aggregate functions only in a single column.
The both will get the same result.
On SQL Server pivot query using UNION ALL of two pivot queries multiple aggregations can be implemented easily. ;WITH PivotData AS ( SELECT [CustomerID], -- grouping column [ShipMethodID], -- spreading column [ShipMethodID]+1000 as [ShipMethodID2], freight -- aggregation column ,CurrencyRateID FROM [Sales].
Simple Solution That Works on All Databases: Filtered Aggregate Functions (or Manual Pivot) This solution allows for calculating all results in a single query by using 8 different, explicit, filtered aggregate functions and no GROUP BY clause (none in this example.
Yes.
Just use the old style CASE
syntax.
SELECT AVG(CASE WHEN Year = 2001 THEN Score END) AS 2001_Avg,
STDEV(CASE WHEN Year = 2001 THEN Score END) AS 2001_StDev /*...*/
PIVOT
is just (less versatile) syntactic sugar for this anyway.
Oracle supports multiple aggregates in PIVOT
but TSQL doesn't.
use case statements. You have to specify all columns anyway and I'd say that case is more usable than pivot
select
avg(case when [Year] = 2001 then [Score] else null end) as [2001_Avg],
avg(case when [Year] = 2002 then [Score] else null end) as [2002_Avg]
from Table1
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With