How to pivot without knowing fixed columns in T-SQL

前端 未结 3 1838
失恋的感觉
失恋的感觉 2020-12-20 01:04

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

相关标签:
3条回答
  • 2020-12-20 01:17

    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
    
    0 讨论(0)
  • 2020-12-20 01:20

    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
    
    0 讨论(0)
  • 2020-12-20 01:31

    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

    1. Use STRING_AGG (From SQL Server 2017 and late)
    SELECT STRING_AGG(QUOTENAME(Col), ', ')
    from (SELECT DISTINCT Col FROM #b) A
    // Output: [1], [2], [3]
    
    1. Use XML Extensions
    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

    0 讨论(0)
提交回复
热议问题