简体   繁体   中英

SQL Server Management Studio - UNPIVOT Query for n columns, n rows

I wanted to unpivot a dataset which looks like this:

在此输入图像描述

To this:

+-------------+-----------------+---------+
| Scenario ID | Distribution ID |  Value  |
+-------------+-----------------+---------+
|           0 | Number1         |      10 |
|           0 | Number2         |      19 |
|           0 | Number3         |    34.3 |
|           0 | Number4         |   60.31 |
|           0 | Number5         | 104.527 |
+-------------+-----------------+---------+

Using SQL System Management Studio.

I think I should use a code which is based on something like this:

SELECT *
FROM
(
  SELECT 1
  FROM table_name
) AS cp 
UNPIVOT 
(
  Scenario FOR Scenarios IN (*
) AS up;

Can anyone help me with this? I do not know how to code, just starting. Thanks in advance!

You could use VALUES :

SELECT T.scenarioId, s.*
FROM tab t
CROSS APPLY (VALUES ('Number1', t.Number1),
                    ('Number2', t.Number2)) AS s(DistId, Val)

I use cross apply for this:

select t.scenarioid, v.*
from t cross apply
     (values ('Number1', number1), ('Number2', number2), . . . 
     ) v(distributionId, number);

You need to list out all the numbers.

Why do I prefer cross apply over unpivot ? I find the unpivot syntax to be very specific. It pretty much does exactly one thing. On the other hand, apply introduces lateral joins. These are very powerful, and apply can be used in many different situations.

I would use apply :

select t.scenarioid, tt.distributionId, tt.value
from table t cross apply
     ( values (Number1, 'Number1'), (Number2, 'Number2'), . . .   
     ) tt (value, distributionId);

Yes, you need to list out all possible Numbers first time only.

In case you need a dynamic unpivot solution (that can handle any number of columns) try this:

create table [dbo].[Test] ([ScenarioID] int,        [Number1] decimal(10,3), 
                           [Number2] decimal(10,3), [Number3] decimal(10,3),
                           [Number4] decimal(10,3), [Number5] decimal(10,3)) 

insert into [dbo].[Test] select 0, 10, 19, 34.3, 60.31, 104.527

declare @sql  nvarchar(max) = '' 
declare @cols nvarchar(max) = '' 

select @cols = @cols +','+ QUOTENAME(COLUMN_NAME) 
from INFORMATION_SCHEMA.COLUMNS 
where TABLE_SCHEMA='dbo' and TABLE_NAME='test' and COLUMN_NAME like 'Number%' 
order by ORDINAL_POSITION 

set @cols = substring(@cols, 2, LEN(@cols)) 

set @sql = @sql + ' select u.[ScenarioID], u.[DistributionID], u.[Value]  
                     from [dbo].[Test] s  
                     unpivot  
                     (  
                     [Value]   
                     for [DistributionID] in ('+ @cols + ')  
                     ) u;' 

execute(@sql)

Result:

在此输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM