Reputation: 115
I have a query like this
SELECT
totalvolume = SUM(volume),
totalusage = SUM(usage),
percentage = CAST(SUM(usage) * 100 / SUM(volume) as decimal (10,2)),
YEAR
FROM
table1
and I get table like below
|totalvolume|totalusage|percentage|Year
|--------------------------------------
| 100 | 50 | 50.00 |2016
| 200 | 50 | 25.00 |2015
My goal is to make the list table goes like this using PIVOT
:
|Type |2015 |2016 |
|------------------------ |
| totalvolume| 200 | 100 |
| totalusage | 50 | 50 |
| percentage |25.00|50.00 |
So I decide to create this table first using a) UNPIVOT
:
Type | Value | year
-------------------
totalvolume |100 |2016
totalusage |50 |2016
percentage |50.00 |2016
totalvolume |200 |2015
totalusage |50 |2015
percentage |25.00 |2015
but in my UNPIVOT
query
SELECT
Type, Value, Year
FROM
<my table query>
UNPIVOT
(value FOR Type IN (totalvolume, totalusage, percentage))
There's an error in my SQL:
The type of column "percentage" conflicts with the type of other columns specified in the UNPIVOT list
So is there any solution to solve this problem without changing the data type?
If I exclude the percentage column I could get the view I want using pivot so it be like this
|Type |2015 |2016 |
|------------------------ |
| totalvolume| 200 | 100 |
| totalusage | 50 | 50 |
But I need the percentage row, too.
Thanks in advance
Upvotes: 4
Views: 13686
Reputation: 1
Using the system tables you could do something like this. if you wanted to add a where clause or something else you could do it in the dynamic sql.
Declare @TableName nvarchar(50), @PrimaryKey nvarchar(50)
Select @TableName = 'TableName', @PrimaryKey = 'PrimaryKey(or unpivot value)'
Declare @JsonConvertColumns nvarchar(max), @UnpivotColumns nvarchar(max)
Declare @SQLQuery nvarchar(max)
select @JsonConvertColumns = Coalesce(@JsonConvertColumns + ',','') + ' string_escape(cast('+columns.name+' as nvarchar(max)), ''JSON'') as ' + columns.name + '' from sys.columns
left join sys.tables on tables.object_id = columns.object_id
where tables.name = @TableName and columns.name <> @PrimaryKey
select @UnpivotColumns = Coalesce(@UnpivotColumns + ',','') + QuoteName(columns.name) from sys.columns
left join sys.tables on tables.object_id = columns.object_id
where tables.name = @TableName and columns.name <> @PrimaryKey
Set @SQLQuery = N'SELECT ' + @PrimaryKey + ', FieldName, FieldValue
FROM (select ' + @PrimaryKey + ', ' + @JsonConvertColumns + ' from ' + @TableName + ') a UNPIVOT
(
FieldValue
FOR FieldName IN (' + @UnpivotColumns + ')
) as p'
Exec sp_executesql @SQLQuery
Upvotes: 0
Reputation: 17925
In this case you can convert to a common numeric format for the pivot operation and then format the options for final output.
with data(totalvolume, totalusage, percentage, Year) as (
select 100, 50, 50.00, 2016 union all
select 200, 50, 25.00, 2015
), converted(totalvolume, totalusage, percentage, Year) as (
select
cast(totalvolume as decimal(8, 2)),
cast(totalusage as decimal(8, 2)),
cast(percentage as decimal(8, 2)),
cast(Year as decimal(8, 2))
from data
)
select
Type,
case
when Type in ('totalvolume', 'totalusage') then format(Value, '0')
when Type = 'percentage' then format(Value, '0.00\%')
end as Value,
format(Year, '0') as Year
from converted unpivot
(value for Type int (totalvolume, totalusage, percentage)) as unpvt
order by
Year, Type desc;
Upvotes: 1
Reputation: 2882
There is no way to have different data types within one column. But you can simulate it by converting all the values to varchar like below
SELECT
Type, Value, Year
FROM
(select
convert(varchar(100), totalvolume) as totalvolume,
convert(varchar(100), totalusage) as totalusage,
convert(varchar(100), percentage) as totalusage
from <my table query>) pv
UNPIVOT
(value FOR Type IN (totalvolume, totalusage, percentage)) unp
Then, if you need to do some calculations, you will have to do reversal conversions.
Upvotes: 6