Home > Software design >  Rows to Columns without aggregation
Rows to Columns without aggregation

Time:12-15

Original table:

 -------------- ----------- ----------------------- 
| Key          | Field     |  Value                |
 -------------- ----------- ----------------------- 
| Foo          | A         |  1                    |
| Foo          | B         |  2                    |
| Foo          | C         |  null                 |
| Foo          | D         |  bar                  |
 -------------- ----------- ----------------------- 

Result should be:

 -------------- --- --- ------ ----- 
| Key          | A | B | C    | D   |
 -------------- --- --- ------ ----- 
| Foo          | 1 | 2 | null | bar |
 -------------- --- --- ------ ----- 

What I've tried:

SELECT 
    [Key] AS Id,
    CASE WHEN Field = 'A' THEN Value END AS ACol,
    CASE WHEN Field = 'B' THEN Value END AS BCol,
    CASE WHEN Field = 'C' THEN Value END AS CCol,
    CASE WHEN Field = 'D' THEN Value END AS DCol
FROM MyTable
GROUP BY [Key]

I'm getting

Column 'Field' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Column 'Value' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Any ideas why?

CodePudding user response:

You need to take the max of the CASE expressions:

SELECT 
    [Key] AS Id,
    MAX(CASE WHEN Field = 'A' THEN Value END) AS ACol,
    MAX(CASE WHEN Field = 'B' THEN Value END) AS BCol,
    MAX(CASE WHEN Field = 'C' THEN Value END) AS CCol,
    MAX(CASE WHEN Field = 'D' THEN Value END) AS DCol
FROM MyTable
GROUP BY [Key];

CodePudding user response:

Assuming T-SQL and sql Server 2019, here is a solution for dynamic pivot as well.

create table random (keys VARCHAR(20), field VARCHAR(20), value VARCHAR(20));

insert into random values ('foo', 'A', '1');
insert into random values ('loo', 'Z', '2');
insert into random values ('foo', 'C', null);
insert into random values ('shi', 'D', 'bar');
insert into random values ('mashi', 'E', 'bla');
insert into random values ('urshi', 'F', 'blue');

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

select * from random
set @cols= stuff((select distinct (',' quotename(field)) from random for xml path(''), type).value('.','NVARCHAR(MAX)'),1,1,'');
set @query = 'select keys,' @cols ' from random pivot(max(value) for field in(' @cols ')) as pivottbl';

execute(@query);
  •  Tags:  
  • sql
  • Related