For this type of data transformation you will want to use the PIVOT
function that is available in SQL Server 2005+. There are two ways to apply the pivot function.
If you know the values ahead of time, then you can hard-code the values in the query. Similar to this:
select M1, M2
from
(
select c1, c2,
row_number() over(partition by c1 order by c1, c2) rn
from yourtable
) src
pivot
(
max(c2)
for c1 in (M1, M2)
) piv
See SQL Fiddle with Demo.
But if you have an unknown number of values that you want to transpose into columns, then you can use dynamic SQL to create the query at run-time.
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(C1)
from yourtable
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query = 'SELECT ' + @cols + ' from
(
select C1, C2,
row_number() over(partition by c1 order by c1, c2) rn
from yourtable
) x
pivot
(
max(C2)
for C1 in (' + @cols + ')
) p '
execute(@query)
See SQL Fiddle with Demo.
Both will give the same result, the difference is the dynamic version is flexible if the values will change:
| M1 | M2 |
---------------
| U1 | U4 |
| U2 | U5 |
| U3 | (null) |