Чтобы удовлетворить дополнительное требование, которое вы упомянули в комментариях, я бы добавил CTE, еще немного обработки XML и динамический TSQL к Отличный ответ Вамси Прабхалы (+1 с моей стороны):
--create test table
create table tmp (Item int, [Option] char(1))
--populate test table
insert into tmp values ( 1, 'A') ,( 1, 'B') ,( 2, 'B') ,( 3, 'B') ,( 4, 'B') ,( 4, 'C') ,( 5, 'A') ,( 6, 'A') ,( 6, 'B') ,( 6, 'C') ,( 7, 'A') ,( 7, 'B') ,( 7, 'C') ,( 8, 'A') ,( 8, 'B') ,( 9, 'A') ,(10, 'A') ,(10, 'B')
declare @count int
declare @loop int = 1
declare @dynamicColums nvarchar(max) = ''
declare @sql nvarchar(max) = ''
--count possible values
select @count = max(c.options_count) from (
select count(*) as options_count from tmp group by item
) c
--build dynamic headers for all combinations
while @loop <= @count
begin
set @dynamicColums = @dynamicColums + ' Parts.value(N''/x['+ cast(@loop as nvarchar(max)) +']'', ''char(1)'') AS [Option ' + cast(@loop as nvarchar(max)) + '],'
set @loop = @loop + 1
end
--build dynamic TSQL statement
set @sql = @sql + ';WITH Splitted'
set @sql = @sql + ' AS ('
set @sql = @sql + ' SELECT ItemComboCount'
set @sql = @sql + ' ,ItemCombo'
set @sql = @sql + ' ,CAST(''<x>'' + REPLACE(ItemCombo, '','', ''</x><x>'') + ''</x>'' AS XML) AS Parts'
set @sql = @sql + ' FROM '
set @sql = @sql + ' ('
set @sql = @sql + ' SELECT ItemCombo, Count(*) AS ItemComboCount'
set @sql = @sql + ' FROM'
set @sql = @sql + ' ('
set @sql = @sql + ' SELECT'
set @sql = @sql + ' Item '
set @sql = @sql + ' ,STUFF((SELECT '','' + CAST([Option] AS varchar(MAX))'
set @sql = @sql + ' FROM tmp a '
set @sql = @sql + ' WHERE a.Item = b.Item'
set @sql = @sql + ' ORDER BY [Option]'
set @sql = @sql + ' FOR XML PATH(''''), TYPE).value(''.'', ''VARCHAR(MAX)''),1,1,'''''
set @sql = @sql + ' ) AS ItemCombo'
set @sql = @sql + ' FROM tmp b'
set @sql = @sql + ' GROUP BY item'
set @sql = @sql + ' ) AS Combos'
set @sql = @sql + ' GROUP BY ItemCombo'
set @sql = @sql + ' ) t'
set @sql = @sql + ' )'
set @sql = @sql + ' SELECT '
set @sql = @sql + @dynamicColums
set @sql = @sql + ' ItemComboCount as [Count]'
set @sql = @sql + ' FROM Splitted'
--execute dynamic TSQL statement
exec(@sql)
Результаты:
Теперь, если вы добавите другое значение (например, 'D') с парой операторов вставки:
insert into tmp values ( 1, 'D')
insert into tmp values ( 7, 'D')
вы увидите, что новые столбцы динамически генерируются: