2012-08-27 4 views
2

je l'ensemble de données suivantlignes et colonnes Transposer sans agrégat

Date   Field1  Col1 Col2 Col3 
2012/07/02  Customer1  CL DS  RT 
2012/07/03  Customer1  DS RT  700 
2012/07/04  Customer1  DS RT  700 
2012/07/02  Customer2  CL DS  RT 
2012/07/03  Customer2  DS RT  1500 
2012/07/04  Customer2  DS RT  1500 
2012/07/02  Customer3  CL DS  RT 
2012/07/03  Customer3  DS RT  6000 
2012/07/04  Customer3  DS RT  6000 
2012/07/02  Customer4  CL RC  RT 
2012/07/03  Customer4  RC RT  4900 
2012/07/04  Customer4  RC RT  4900 

Je voudrais sortie comme suit:

Field1 2012/07/02 2012/07/03 2012/07/04 
Col1 Customer1 CL DS DS 
Col2 Customer1 DS RT RT 
Col3 Customer1 RT 700 700 
Col1 Customer2 CL DS DS 
Col2 Customer2 DS RT RT 
Col3 Customer2 RT 1500 1500 
Col1 Customer3 CL DS DS 
Col2 Customer3 DS RT RT 
Col3 Customer3 RT 6000 6000 
Col1 Customer4 CL RC RC 
Col2 Customer4 RC RT RT 
Col3 Customer4 RT 4900 4900 

Le problème est aussi que j'ai un montant non fixé des clients (Champ1 & quantité non fixée de dates.

Répondre

0

Vous n'avez pas besoin de le faire sans agrégats, mais vous devez utiliser Dynamic SQL pour le faire. Recherchez "SQL Dynamic Pivot" et vous trouverez de nombreux articles à ce sujet. Comme: SQL Server dynamic PIVOT query?

Mais mieux vaut le faire dans le client, car les clients SQL préfèrent savoir quelles colonnes sont produites à l'avance.

2

Ce que vous essayez de faire est connu comme PIVOT. Il y a deux façons de le faire, soit avec un pivot statique où vous codez en dur toutes les valeurs à transformer, soit un pivot dynamique où les valeurs ont été déterminées lors de l'exécution.

Version statique (Voir SQL Fiddle with Demo):

select * 
from 
(
    select dt, field1, col, value 
    from yourTable 
    unpivot 
    (
    value for col in (col1, col2, col3) 
) u 
)x1 
pivot 
(
    min(value) 
    for dt in ([2012-07-02], [2012-07-03], [2012-07-04]) 
) p 

Dynamic Pivot (Voir SQL Fiddle with Demo):

DECLARE @colsUnpivot AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX), 
    @colsPivot as NVARCHAR(MAX) 

select @colsUnpivot = stuff((select ','+quotename(C.name) 
     from sys.columns as C 
     where C.object_id = object_id('yourTable') and 
       C.name like 'col%' 
     for xml path('')), 1, 1, '') 

select @colsPivot = STUFF((SELECT distinct ', ' + QUOTENAME(convert(char(10), dt, 120)) 
        from yourTable 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 
      'SELECT col, field1, ' + [email protected]+ ' 
      FROM 
      (
       select dt, field1, col, value 
       from yourTable 
       unpivot 
       (
       value for col in ('+ @colsUnpivot+') 
      ) u 
      )x1 
      pivot 
      (
      min(value) 
      for dt in ('[email protected]+') 
      ) p ' 

exec(@query) 

Le pivot dynamique est une excellente option lorsque vous ne connaissez pas le nombre d'articles que vous besoin de convertir en colonnes. Les deux vont donner les mêmes résultats.

Edit # 1, si vous voulez que les colonnes de date dans un ordre spécifique - desc, etc, vous utiliserez ce qui suit pour obtenir les dates (voir SQL Fiddle with Demo):

select @colsPivot = STUFF((SELECT ', ' + QUOTENAME(convert(char(10), dt, 120)) 
        from yourTable 
        group by dt 
        ORDER by dt desc 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 
+0

Je dois aussi commander les dates correctement. Comment est-ce que je fais ceci dans la version dynamique car elle apprend incorrectement commandée actuellement avec plus de données ajoutées? – user1627440

+0

@ user1627440 S'il vous plaît voir ma modification, vous modifierez légèrement le code lors de la rotation de la liste des colonnes. – Taryn

0

Vous devez utiliser SQL Server Pivot query pour ta question.

que vous pouvez utiliser en dessous de la requête:

CREATE TABLE mytable(date DATE, Field1 NVARCHAR(50), col1 NVARCHAR(30), col2 NVARCHAR(30),col3 NVARCHAR(30)) 
INSERT INTO mytable(date,Field1,col1,col2,col3) 
VALUES('2012/07/02','Customer1','CL','DS','RT') 
... 

SELECT Col, Field1, [2012/07/02],[2012/07/03],[2012/07/04] 
FROM (SELECT Field1, 'Col1' AS Col, Date, Col1 AS ColVal 
     FROM MyTable 

     UNION ALL 

     SELECT Field1, 'Col2' , Date, Col2 AS ColVal 
     FROM MyTable 

     UNION ALL 

     SELECT Field1, 'Col3' , Date, Col3 AS Col 
     FROM MyTable 
    )AS P 
PIVOT (MIN(Colval) FOR Date IN ([2012/07/02],[2012/07/03],[2012/07/04])) AS Pvt 
ORDER BY Field1, Col 
Questions connexes