-4

I Have table having 2 columns

Column1 Value
   A     10 
   B     20 
   C     11
   A     40 
   B     30 
   C     22

I Want Result like

Column1 Value1 Value2
A       10      40
B       20      30
C       11      22

Is there any query or store Procdure to get such Output

4 Answers4

3

If there's more then 2 Value columns then MIN & MAX won't do.

Then you can use ROW_NUMBER to calculate numbered values, and use that in a PIVOT

SELECT *
FROM
(
    SELECT Column1, [Value]
    , Col = CONCAT('Value', ROW_NUMBER() OVER (PARTITION BY Column1 ORDER BY [Value]))
    FROM YourTable
) Src
PIVOT (
    MAX([Value])
     -- add more columns here
    FOR Col IN (Value1, Value2)
) Pvt
LukStorms
  • 28,916
  • 5
  • 31
  • 45
3

If you don't know for sure how many values per Column1 there will be, you'll have to do dynamic SQL.

Adapting @LukStorms excellent answer above:

IF OBJECT_ID('tempdb..#MyTable') IS NOT NULL
    DROP TABLE #MyTable


create table #MyTable (c nvarchar(1), v int)

insert into #MyTable
select 'A',10
union select 'B',20
union select 'C',11
union select 'A',40
union select 'B',30
union select 'C',22
union select 'A',60
union select 'C',28
union select 'C',150

declare @s varchar(max), @maxVals int, @i int = 1

select @maxVals = max(ct) from (select c,count(*) as ct from #MyTable group by c) as x

set @s = 'SELECT *
FROM
(
    SELECT c as Column1, v
    , Col = CONCAT(''Value'', ROW_NUMBER() OVER (PARTITION BY c ORDER BY v))
    FROM #MyTable
) Src
PIVOT (
    MAX(v)
    FOR Col IN ('

while @i <= @maxVals
begin

set @s = @s + 'Value' + cast(@i as varchar)

if @i < @maxVals
     set @s = @s + ', '

set @i = @i +1
end

set @s = @s + ')
) Pvt'

exec(@s)

Note that SQL won't necessarily keep the order the values were inserted, unless you use an identity column and sort on that. Also, if a column1 has more than one value the same, it will ignore the duplicate.

Hope that helps, and thanks @LukStorms for the initial work

the Ben B
  • 166
  • 8
2

It can also be done dynamically as bellow since you are not sure of the number of columns by modifying @LukStorms answer

create table #MyTable (Column1 VARCHAR(2), [Value] INT)
insert into #MyTable values
('A',10),('B',20),('C',11),
('A',40), ('B',30), ('C',22)



 DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);

SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(CONCAT('Value', ROW_NUMBER() OVER (PARTITION BY Column1 ORDER BY [Value]))) 
            FROM #MyTable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query =  'SELECT 
                * 
              FROM
            ( SELECT Column1, [Value],
            CONCAT(''Value'', ROW_NUMBER() OVER (PARTITION BY Column1 ORDER BY [Value])) AS ColValue
                FROM #MyTable
            ) Src
            PIVOT (
                MAX([Value]) FOR ColValue IN ('+@cols+')  
) Pvt'

 exec(@query)

 drop table #MyTable
JonWay
  • 1,585
  • 17
  • 37
1

You require DynamicSql + Pivot operation.I am not aware of any other method.

The below query will give you what you want.

DROP TABLE tmptbl
GO
SELECT * ,
    'Value' + (CONVERT(NVARCHAR(MAX), ROW_NUMBER() OVER (PARTITION BY [Column1] ORDER BY Column1,[Value]))) [ValueColumn]
INTO tmptbl
FROM (
SELECT 'A' [Column1],10 [Value]
UNION ALL
SELECT 'A' [Column1],20 [Value]
UNION ALL
SELECT 'A' [Column1],30 [Value]
UNION ALL
SELECT 'B' [Column1],40 [Value]
UNION ALL
SELECT 'B' [Column1],50 [Value]
UNION ALL
SELECT 'B' [Column1],60 [Value]
UNION ALL
SELECT 'B' [Column1],70 [Value]
) tbl
GO
DECLARE @Vals NVARCHAR(MAX)
SET @Vals = N''
SELECT @Vals = STUFF((SELECT ', ' + QUOTENAME('Value' + CONVERT(NVARCHAR(MAX), ROW_NUMBER() OVER (ORDER BY [Valuecolumn])))
                FROM tmptbl
                GROUP BY [Valuecolumn]
                FOR XML PATH ('')),1,1,'')
SELECT @vals

DECLARE @strsql NVARCHAR(MAX) = ' SELECT [Column1],' + @vals + ' 
                                  FROM (
                                     SELECT [Column1],[Value],[ValueColumn]
                                     FROM tmptbl
                                       ) t
                                  PIVOT (
                                  AVG([Value])
                                  FOR [ValueColumn] IN (' + @Vals + ')) As p'
EXEC (@strsql)
Cogent
  • 404
  • 7
  • 16