I have a table called balance
which I wish to pivot, however it is quite difficult since the column names would be labelled 1,2,3 and balances would be sorted b
Try this.
declare @balanceAMTCols varchar(max)='',
@statement nvarchar(4000)=''
select @balanceAMTCols= stuff(
(
select ','+ QUOTENAME(balanceamtcol) from (
select distinct convert(varchar(10),(row_number() over(partition by Customer order by Customer)))
balanceamtcol FROM #a ) as tbl
for xml path('')),1,1,'')
set @statement= 'select Customer,'+@balanceAMTCols+' from (
select Customer,Balance,convert(varchar(10),(row_number() over(partition by Customer order by Customer))) as balanceamtcol FROM #a
) [CustomerTbl]
pivot
(
max(Balance)
for balanceamtcol
in ('+@balanceAMTCols+') ) as pivatetble'
exec sp_executesql @statement
You can try this way
select *,concat('Price',RANK() OVER (PARTITION BY i.REFERENCE_NO ORDER BY i.TASK_ID
DESC)) AS Rank into #temp from [dbo].[Table_1] i
select REFERENCE_NO,Price1,Price2,Price3 from
(
select REFERENCE_NO,TASK_ID,Rank from #temp
) as cte
PIVOT (SUM(TASK_ID)
FOR rank IN (Price1,Price2,Price3 ))
as PVT
Demo on db<>fiddle
You can use ROW_NUMBER() to mark the number of values, e.g: 1, 2, 3
.
Note that: ORDER BY [Balance] DESC
to get the generated value as you wish.
DECLARE
@columns NVARCHAR(MAX) = '',
@sql NVARCHAR(MAX) = '';
SELECT Customer, Balance, Col = ROW_NUMBER() OVER (PARTITION BY Customer ORDER BY [Balance] DESC)
into #b
FROM #a
SELECT @columns += QUOTENAME(Col) + ','
from (SELECT DISTINCT Col FROM #b) A
-- remove the last comma
SET @columns = LEFT(@columns, LEN(@columns) - 1);
SET @sql = 'SELECT * FROM ( SELECT Customer, Balance, Col FROM #b) src PIVOT( MAX([Balance]) FOR Col IN ('+ @columns +')) AS pivot_table;';
-- execute the dynamic SQL
EXECUTE sp_executesql @sql;
Output
Updated
Since concatenating strings is undocumented and unreliable. It does not always work as expected. So you should resolve with 2 solutions below
SELECT STRING_AGG(QUOTENAME(Col), ', ')
from (SELECT DISTINCT Col FROM #b) A
// Output: [1], [2], [3]
DECLARE @columns NVARCHAR(MAX) = ''
SELECT @columns = (
SELECT QUOTENAME(Col) + ', '
FROM (SELECT DISTINCT Col FROM #b) A
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
SELECT @columns
// Output: [1], [2], [3],
Thanks @GarethD's comment. Check it out on db<>fiddle