How to make data rows become grouped columns?

I want to group by ID, but each group of columns is displayed as a new horizontal set of columns.

I have a table with data like this

╔════╦═══════╦════════╗
β•‘ ID β•‘ Phone β•‘  Type  β•‘
╠════╬═══════╬════════╣
β•‘  A β•‘   111 β•‘ home   β•‘
β•‘  A β•‘   222 β•‘ work   β•‘
β•‘  B β•‘   333 β•‘ cell   β•‘
β•‘  B β•‘   444 β•‘ school β•‘
β•šβ•β•β•β•β•©β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•

I want it to look like

╔════╦════════╦═══════╦════════╦════════╗
β•‘ ID β•‘ Phone1 β•‘ Type1 β•‘ Phone2 β•‘ Type2  β•‘
╠════╬════════╬═══════╬════════╬════════╣
β•‘  A β•‘    111 β•‘ home  β•‘    222 β•‘ work   β•‘
β•‘  B β•‘    333 β•‘ cell  β•‘    444 β•‘ school β•‘
β•šβ•β•β•β•β•©β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•©β•β•β•β•β•β•β•β•β•

Ideally, I would find a solution that would handle an arbitrary number of repeating groups, but I could hardcode the number if I had to.

I can have up to 100,000 unique identifiers with 20 repeating sets of column groups, each of which can contain up to 5 separate columns.

PIVOT seems to help in this, but I cannot figure out how to do this.

EDIT: , , . , . . PIVOT, , ( -, !)

SQL Server 2012

+4
1

-, sql.

. http://www.sqlservercentral.com/articles/Crosstab/65048/

if OBJECT_ID('tempdb..#Something') is not null
    drop table #Something

create table #Something
(
    ID char(1)
    , Phone int
    , MyType varchar(10)
)

insert #Something
select 'A', 111, 'home' union all
select 'A', 222, 'work' union all
select 'B', 333, 'cell' union all
select 'B', 444, 'school'

select *
from #Something

declare @StaticPortion nvarchar(2000) = 
'with OrderedResults as
(
    select *
        , ROW_NUMBER() over (partition by ID order by phone) as RowNum
    from #Something
)
select ID';

declare @DynamicPortion nvarchar(max) = '';
declare @FinalStaticPortion nvarchar(2000) = ' from OrderedResults Group by ID order by ID';


with E1(N) AS (select 1 from (values (1),(1),(1),(1),(1),(1),(1),(1),(1),(1))dt(n)),
E2(N) AS (SELECT 1 FROM E1 a, E1 b), --10E+2 or 100 rows
E4(N) AS (SELECT 1 FROM E2 a, E2 b), --10E+4 or 10,000 rows max
cteTally(N) AS 
(
    SELECT  ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) FROM E4
)

select @DynamicPortion = @DynamicPortion + 
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then Phone end) as Phone' + CAST(N as varchar(6)) +
    ', MAX(Case when RowNum = ' + CAST(N as varchar(6)) + ' then MyType end) as Type' + CAST(N as varchar(6))

from cteTally t
where t.N <= 
(
    select top 1 Count(*)
    from #Something
    group by ID
    order by COUNT(*) desc
)

select @StaticPortion + @DynamicPortion + @FinalStaticPortion

declare @SqlToExecute nvarchar(max) = @StaticPortion + @DynamicPortion + @FinalStaticPortion;
exec sp_executesql @SqlToExecute
+1

Source: https://habr.com/ru/post/1608339/


All Articles