Search code examples
sqlsql-servert-sqlpivotunpivot

How can I unpivot three types of values (including the column headers)


The data I have looks like this:

╔═════════╦═════════╦═════════╦══════════════╦══════════════╦══════════════╗
║ option1 ║ option2 ║ option3 ║ percent_opt1 ║ percent_opt2 ║ percent_opt3 ║
╠═════════╬═════════╬═════════╬══════════════╬══════════════╬══════════════╣
║ 10      ║ 4       ║ 1       ║ 0.67         ║ 0.27         ║ 0.07         ║
╚═════════╩═════════╩═════════╩══════════════╩══════════════╩══════════════╝

So if i want to make the first three column headers row values, then the other ones also as more row values, how would I do that?

This is what I mean:

╔═════════╦════════╦═════════════╗
║ options ║ values ║ percentages ║
╠═════════╬════════╬═════════════╣
║ option1 ║ 10     ║ 0.67        ║
╠═════════╬════════╬═════════════╣
║ option2 ║ 4      ║ 0.27        ║
╠═════════╬════════╬═════════════╣
║ option3 ║ 1      ║ 0.07        ║
╚═════════╩════════╩═════════════╝

Here is the code I'm using:

declare @tbl as table (
    option1 numeric(18,0),
    option2 numeric(18,0),
    option3 numeric(18,0),
    per_opt1 numeric(18,2),
    per_opt2 numeric(18,2),
    per_opt3 numeric(18,2)
)

insert into @tbl
values (10,4,1,0.67,0.27,0.07)

;

select * from
(
    select t.[option1],t.[option2],t.[option3]
    from @tbl as t
) as srctbl
    unpivot (
        val for options in (option1,option2,option3)
) as unpiv

I don't know how to get those last three percentage column values to be row values, partially because I can't have a different datatype, and because I'm not sure how to.

Any suggestions?


Solution

  • Use apply:

    select v.*
    from @tbl t cross apply
         (values ('option1', option1, percent_opt1),
                 ('option2', option2, percent_opt2),
                 ('option3', option3, percent_opt3)
         ) v(option, value, percent_opt);
    

    Note: values is a SQL keyword so I changed the name of the middle column.

    In my opinion, there is no reason whatsoever to learn unpivot. It is bespoke functionality -- extensions in a small number of databases -- that does just one thing in an "okay" way.

    On the other hand, apply supports lateral joins, which are standard (even if the syntax varies among databases). They are very powerful, and unpivoting is a good way to start learning about them.