Pivoter plusieurs colonnes dans des lignes dans SQL Server?

J'ai une table avec des données comme celle-ci

create table temp ( colName varchar(50), name varchar(50), icon varchar(150), totalcount int ) insert into temp values ('Eng1', 'Following', 'followingicon.png', 1564) insert into temp values ('Eng2','Total Followers', 'followericon.png', 500) insert into temp values ('Eng3','Direct Messages', 'messageicon.png', 800) 

Comment puis-je sélectionner et faire apparaître datatables

Résultat final

avec Eng1, Eng2 et Eng3 étant en-têtes de colonne

C'est ce que j'ai obtenu jusqu'ici mais ça ne fait que le premier niveau. J'ai besoin de tous les trois niveaux

 DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) FROM temp c FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT ' + @cols + ' from ( select colName , totalcount from temp ) x pivot ( max( totalcount) for colName in (' + @cols + ') ) p' execute(@query) 

J'utilise SQL Server 2008.

Merci de votre aide!

Voici un moyen:

 DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) FROM #temp c FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') SET @query = 'SELECT ' + @cols + ' FROM ( SELECT y.* FROM #Temp t CROSS APPLY ( VALUES (t.colname,CONVERT(VARCHAR(150),name),''name''), (t.colname,icon,''icon''), (t.colname,CONVERT(VARCHAR(150),totalcount),''totalcount'') ) y (colName, value, Data) ) x PIVOT ( MAX(Value) FOR colName IN (' + @cols + ') ) p' EXECUTE(@query) 

Ma suggestion lorsque vous travaillez avec SQL dynamic serait d'écrire une version codée en dur de la requête d'abord pour get la logique correcte, puis le convertir en SQL dynamic.

Pour get le résultat, vous devez commencer par resize les colonnes de name , d' icon et de totalcount , puis appliquer le pivot pour créer vos nouvelles colonnes. Vous pouvez utiliser la fonction UNPIVOT ou CROSS APPLY pour transformer les colonnes en lignes. La requête pour convertir datatables de colonnes en lignes serait:

 select colname, origCol, value from temp cross apply ( select 'name', name union all select 'icon', icon union all select 'totalcount', cast(totalcount as varchar(50)) ) c (origCol, value) 

Voir la démo . Cela vous donne datatables au format:

 | COLNAME | ORIGCOL | VALUE | | Eng1 | name | Following | | Eng1 | icon | followingicon.png | | Eng1 | totalcount | 1564 | | Eng2 | name | Total Followers | 

Ensuite, vous pouvez appliquer la fonction PIVOT à vos nouvelles valeurs de colname :

 select Eng1, Eng2, Eng3 from ( select colname, origCol, value from temp cross apply ( select 'name', name union all select 'icon', icon union all select 'totalcount', cast(totalcount as varchar(50)) ) c (origCol, value) ) src pivot ( max(value) for colname in (Eng1, Eng2, Eng3) ) piv 

Voir SQL Fiddle avec démo . Comme je l'ai dit, vous avez besoin d'une version dynamic, maintenant que vous avez la logique correcte, vous pouvez le convertir en une requête SQL dynamic:

 DECLARE @cols AS NVARCHAR(MAX), @query AS NVARCHAR(MAX); SET @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.colName) FROM temp c FOR XML PATH(''), TYPE ).value('.', 'NVARCHAR(MAX)') ,1,1,'') set @query = 'SELECT ' + @cols + ' from ( select colname, origCol, value from temp cross apply ( select ''name'', name union all select ''icon'', icon union all select ''totalcount'', cast(totalcount as varchar(50)) ) c (origCol, value) ) x pivot ( max(value) for colName in (' + @cols + ') ) p' execute sp_executesql @query; 

Voir SQL Fiddle avec démo . Cela donnera un résultat:

 | ENG1 | ENG2 | ENG3 | | followingicon.png | followericon.png | messageicon.png | | Following | Total Followers | Direct Messages | | 1564 | 500 | 800 |