transposing rows into cols without using agg function

Northface 161 Reputation points
2022-02-18T10:05:44.073+00:00

Hi there,

I want to get the same number of rows into columns "as is" without defining values in the relationship between both.

DECLARE @t1 AS TABLE(Id2 tinyint, concept varchar(5))

insert into @t1(Id2, concept)

values (1,'abc'),(2,'abc2'),(3,'def'),(4,'nil'),(5,'chk')

select * from @t1

desireout outcome would be the following:

Ideally the code should be dynamic as this is only a POC and the definitive topic contains about 60 rows..

175803-xxxxx.png

Transact-SQL
Transact-SQL
A Microsoft extension to the ANSI SQL language that includes procedural programming, local variables, and various support functions.
4,625 questions
{count} votes

Accepted answer
  1. LiHong-MSFT 10,046 Reputation points
    2022-02-21T08:58:31.177+00:00

    Hi @Northface
    Please check this:

    DECLARE @sql_str NVARCHAR(MAX)  
    DECLARE @spread_elements NVARCHAR(MAX)  
              
    SELECT @spread_elements = ISNULL(@spread_elements + ',','') + QUOTENAME(concept)   
    FROM #t1   
    GROUP BY concept  
      
    SELECT @sql_str = 'select t1.concept,x.* from(select concept,''''as col from #t1)t PIVOT(max(col) for concept in ( ' + @spread_elements + ')) x   
                             cross join #t1 t1 order by concept'  
              
    PRINT @sql_str  
    EXECUTE sp_executeSQL @sql_str;  
    

    Best regards,
    LiHong

    0 comments No comments

3 additional answers

Sort by: Most helpful
  1. Olaf Helper 44,311 Reputation points
    2022-02-18T11:09:11.94+00:00

    Ideally the code should be dynamic as this is only a POC and the definitive topic contains about 60 rows..

    That would be only possible with dynamic SQL and that means a lot of coding.

    A fix defined list of values can be easily achived with a PIVOT query: FROM - Using PIVOT and UNPIVOT

    0 comments No comments

  2. Naomi Nosonovsky 7,856 Reputation points
    2022-02-18T14:13:33.96+00:00

    Try
    DROP TABLE IF EXISTS #t1
    CREATE table #t1(Id2 tinyint, concept varchar(5))

    insert into #t1(Id2, concept)
    
    values (1,'abc'),(2,'abc2'),(3,'def'),(4,'nil'),(5,'chk');
    
    DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);
    
    SELECT @cols = STRING_AGG(quotename (x.concept),',')  WITHIN GROUP (ORDER BY x.concept) FROM (SELECT DISTINCT concept FROM #t1) x
    
    
    PRINT @cols;
    
    SELECT @sql = 'select * from #t1 PIVOT(max(id2) for concept in ( ' + @cols + ')) x'
    
    PRINT @sql
    EXECUTE sp_executeSQL @sql;
    

  3. Tom Cooper 8,466 Reputation points
    2022-02-18T16:20:26.94+00:00
    DROP TABLE IF EXISTS #t1  
    CREATE table #t1(Id2 tinyint, concept varchar(5))  
    insert into #t1(Id2, concept)  
          
     values (1,'abc'),(2,'abc2'),(3,'def'),(4,'nil'),(5,'chk');  
          
     DECLARE @cols NVARCHAR(MAX), @sql NVARCHAR(MAX);  
          
     SELECT @cols = STRING_AGG(quotename (x.concept),',')  WITHIN GROUP (ORDER BY x.concept) FROM (SELECT DISTINCT concept FROM #t1) x  
          
          
     PRINT @cols;  
          
     SELECT @sql = 'select t1.concept, x.* from #t1 PIVOT(max(id2) for concept in ( ' + @cols + ')) x cross join #t1 t1 order by concept'  
          
     PRINT @sql  
     EXECUTE sp_executeSQL @sql;  
    

    Tom

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.