I would like to transform a table from rows to columns in SQL Server.
Given table1:
id value1 value2
1 name1 9
1 name1 26
1 name1 15
2 name2 20
2 name2 18
2 name2 61
I need a table like:
id name1 name2
1 9 0
1 26 0
1 15 0
2 0 20
2 0 18
2 0 61
Can pivot help here? An efficient way is preferred to do the convert because the table is large.
I have tried:
select
id, name1, name2
from
(select
id, value1, value2
from table1) d
pivot
(
max(value2)
for value1 in (name1, name2)
) piv;
But, it cannot provide all rows for same ID to combine with 0s.
Thanks
The 'secret' is to add a column to give uniqueness to each row within your 'nameX' groups. I've used ROW_NUMBER
. Although PIVOT
requires an aggregate, with our 'faked uniqueness' MAX, MIN etc will suffice. The final piece is to replace any NULL
s with 0 in the outer select.
(BTW, we're on 2014 so I can't test this on 2008 - apologies)
SELECT * INTO #Demo FROM (VALUES
(1,'name1',9),
(1,'name1',26),
(1,'name1',15),
(2,'name2',20),
(2,'name2',18),
(2,'name2',61)) A (Id,Value1,Value2)
SELECT
Id
,ISNULL(Name1, 0) Name1
,ISNULL(Name2, 0) Name2
FROM
( SELECT
ROW_NUMBER() OVER ( PARTITION BY Id ORDER BY Id ) rn
,Id
,Value1
,Value2
FROM
#Demo ) A
PIVOT ( MAX(Value2) FOR Value1 IN ( [Name1], [Name2] ) ) AS P;
Id Name1 Name2
----------- ----------- -----------
1 9 0
1 26 0
1 15 0
2 0 20
2 0 18
2 0 61
you can do case based aggregation
with group by
select id,
max(case when value1 ='name1' then value2 else 0 end) as name1,
max(case when value1 ='name2' then value2 else 0 end) as name2
from Table1
group by id, value1, value2
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.