2010-03-23 4 views
2

J'ai une requête qui renvoie une ligne. Toutefois, je souhaite inverser les lignes et les colonnes, ce qui signifie que les lignes sont affichées en tant que colonnes et colonnes en tant que lignes. Je pense que la meilleure façon de le faire est d'utiliser un tableau croisé dynamique, que je ne suis pas expert enComment inverser des lignes et des colonnes à l'aide d'un tableau croisé dynamique T-SQL

Voici ma requête simple:.

SELECT Period1, Period2, Period3 
FROM GL.Actuals 
WHERE Year = 2009 AND Account = '001-4000-50031' 

résultats (en-têtes):

Période1, Period2, PERIOD3

612,58, 681,36, 676,42

I aimerait que les résultats pour ressembler à ceci:

résultats souhaités:

Période, Montant

Jan, 612,58

fév 681,36

Mar, 676,42

Ceci est un exemple simple, mais ce que je ' m vraiment après est un peu plus complexe que cela. Je réalise que je pourrais produire ces résultats en utilisant plusieurs commandes SELECT à la place. J'espère juste que quelqu'un peut faire la lumière sur la façon d'accomplir cela avec un tableau croisé dynamique ou s'il y a encore un meilleur moyen.

Répondre

1

Essayez quelque chose comme ça (testé sur MSSQL2008):

DECLARE @Data TABLE(Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2)) 
INSERT @Data 
VALUES (612.58, 681.36, 676.42) 

SELECT Period, Amount 
FROM (SELECT Period1 AS Jan, Period2 AS Feb, Period3 AS Mar FROM @Data) AS D 
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar)) AS U 

Mise à jour

Basé sur le commentaire de Jeff, que diriez-vous:

DECLARE @Actuals TABLE(Account INT, [Year] INT, Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2)) 
INSERT @Actuals VALUES (1, 2010, 612.58, 681.36, 676.42) 
INSERT @Actuals VALUES (1, 2009, 512.58, 581.36, 576.42) 

SELECT Account, Period, Amount 
FROM 
(
    SELECT a.Account, a.Period1 AS Jan, a.Period2 AS Feb, a.Period3 AS Mar, a1.Period1 AS Jan1, a1.Period2 AS Feb1, a1.Period3 AS Mar1 
    FROM @Actuals AS a 
    LEFT OUTER JOIN @Actuals AS a1 ON a.Account = a1.Account AND a1.[Year] = a.[Year] - 1 
    WHERE a.[Year] = 2010 
) AS d 
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar, Jan1, Feb1, Mar1)) AS u 

ou, avec une année explicite colonne:

DECLARE @Actuals TABLE(Account INT, [Year] INT, Period1 Decimal(5, 2), Period2 Decimal(5, 2), Period3 Decimal(5, 2)) 
INSERT @Actuals VALUES (1, 2010, 612.58, 681.36, 676.42) 
INSERT @Actuals VALUES (1, 2009, 512.58, 581.36, 576.42) 

SELECT Account, [Year], Period, Amount 
FROM 
(
    SELECT a.Account, a.[Year], a.Period1 AS Jan, a.Period2 AS Feb, a.Period3 AS Mar 
    FROM @Actuals AS a WHERE a.[Year] IN (2009, 2010) 
) AS d 
UNPIVOT (Amount FOR Period IN (Jan, Feb, Mar)) AS u 
+0

Ceci est une excellente solution pour l'exemple simple que j'ai donné.Cependant, si j'ai besoin d'inclure une autre colonne, je ne vois pas comment je peux le faire de cette façon. Voir l'exemple ci-dessous. Je fais le JOIN pour l'autre colonne, mais je ne peux pas l'obtenir. SELECT compte, période, [2010 Actual] DE ( \t SELECT a.Account \t, a.Period1 AS Jan, a.Period2 AS fév a.Period3 AS Mar \t, a1.Period1 AS Jan1, a1 .Period2 AS Feb1, a1.Period3 AS Mar1 \t dE GL.Actuals un \t LEFT JOIN GL.Actuals a1 SUR a1.Account = a.Account ET a1.Year = a.Year - 1 \t OÙ a.Year = 2010) AS d UNPIVOT ([2010 Actual] POUR Période IN (Jan, Fév, Mar)) AS –

+0

Intéressant, mais pas exactement ce que je suis après. Dans ce cas, j'ai besoin de deux colonnes, une pour chaque année. –

+0

dans ce cas, après l'unpivot, appliquez un pivot comme ceci: SELECT Compte, Période, [2009], [2010] FROM (...) AS PIVOT DP (MAX (Montant) POUR [Année] IN ([2009] , [2010])) AS P, où ... est le dernier unpivot d'en haut. J'espère que cela pourra aider :) – Adam

2

Pour un ensemble fixe de champs, vous pouvez utiliser UNION d'instructions select, chaque instruction récupérant l'un des champs. SQL standard ne fournit pas un moyen de transposer le résultat pour un nombre variable de champs, par ex. select * from table.

Si MSSQL a une extension qui aide (comme pivot), je ne sais pas à ce sujet.

+1

Maintenant vous: http://msdn.microsoft.com/en-us/library/ms177410.aspx –

+0

Merci, Alison. :) Fait-il partie d'une version du standard SQL ou d'une extension? –

+1

Les tables de Pivote font partie de Transact-SQL, qui est unique à SQL Server 2005 et 2008. –

1

Vérifiez la fonction unnest, c'est assez incroyable avec peu de frais généraux. Il suffit d'ajouter une requête de sélection au-dessus de la requête select imbriquée et unnest à ce moment:

SELECT id, 
    unnest(array['a', 'b', 'c']) AS colname, 
    unnest(array[a, b, c]) AS thing 
FROM foo 
ORDER BY id; 
Questions connexes