Convert row value in to column in SQL server (PIVO

2020-02-01 03:06发布

问题:

I have table in SQL Server called test having 3 column

|  ITEM | ATTRIBUTE | VALUE |
-----------------------------
| item1 |   Quality |     A |
| item1 |     color |   Red |
| item2 |   Quality |     B |
| item2 |     color | Black |

I want output like this:

|  ITEM | QUALITY | COLOR |
---------------------------
| item1 |       A |   Red |
| item2 |       B | Black |

How can I get this in SQL Server.

回答1:

Try this one:

SELECT *
FROM (SELECT Item, attribute, value FROM MyTable) AS t
PIVOT
(
  MAX(value)
  FOR attribute IN([Quality], [Color])
) AS p;

Output:

╔═══════╦═════════╦═══════╗
║ ITEM  ║ QUALITY ║ COLOR ║
╠═══════╬═════════╬═══════╣
║ item1 ║ A       ║ Red   ║
║ item2 ║ B       ║ Black ║
╚═══════╩═════════╩═══════╝

See this SQLFiddle

You can also use this dynamic query if you don't know the specific value of attribute:

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

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(attribute) 
                    from MyTable
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'SELECT Item,' + @cols + ' 
             from 
             (
                Select Item, attribute , value
                from MyTable
             ) dta
             pivot 
             (
                MAX(Value)
                for attribute in (' + @cols + ')
             ) pvt '

execute(@query);

See this SQLFiddle



回答2:

This is a bit of a hacky solution for mysql as PIVOT doesn't work in it.

select item, GROUP_CONCAT('',q) as Quantity, GROUP_CONCAT('',c) as Color from 
(select item ,CASE WHEN attribute = 'Quality' THEN value ELSE NULL END as q, CASE WHEN attribute = 'Color' THEN value ELSE NULL END as c 
 from MyTable
) temp 
group by item

Issue with this solution is that you should know all the distinct values of attribute column.

You can try it here.