SQL Server: exemples de données PIVOTing String

125

Essayer de trouver des exemples simples de SQL Server PIVOT. La plupart des exemples que j'ai trouvés impliquent de compter ou de résumer des nombres. Je veux juste faire pivoter certaines données de chaîne. Par exemple, j'ai une requête renvoyant ce qui suit.

Action1 VIEW  
Action1 EDIT  
Action2 VIEW  
Action3 VIEW  
Action3 EDIT  

Je voudrais utiliser PIVOT (si même possible) pour obtenir les résultats comme suit:

Action1 VIEW EDIT  
Action2 VIEW NULL  
Action3 VIEW EDIT  

Est-ce même possible avec la fonctionnalité PIVOT?

Tim Cochran
la source
Jetez un œil à ce lien: dotnetgalactics.wordpress.com/2009/10/23 /... Pourrait être utile;)
Pato
Vous pouvez voir ce lien si le nombre d'éléments distincts est inconnu, ce qui signifie que le nombre de colonnes après le pivotement est dynamique. SQL Server Pivot: Conversion de lignes en colonnes avec requête dynamique
maeenul

Réponses:

165

N'oubliez pas que la fonction d'agrégation MAX fonctionnera aussi bien sur le texte que sur les nombres. Cette requête ne nécessitera qu'une seule analyse de la table.

SELECT Action,
       MAX( CASE data WHEN 'View' THEN data ELSE '' END ) ViewCol, 
       MAX( CASE data WHEN 'Edit' THEN data ELSE '' END ) EditCol
 FROM t
 GROUP BY Action
John Hubert
la source
+1 Mec ... tu es vraiment un génie. J'aurais aimé le savoir plus tôt, au lieu d'avoir à apprendre à PIVOTER!
ashes999
@ Silmaril89 suppose que le nom de la deuxième colonne en question est «données» et la première colonne est «Action»
Iman
1
Y a-t-il une raison pour laquelle je ne devrais pas utiliser à la ...ELSE NULL END...place de ...ELSE '' END...?
mo.
15
Lequel est le plus rapide, ceci ou PIVOT?
Robert Jeppesen
Whoah, vous venez de souffler mon esprit. Dans le fond de ma tête, j'avais cette idée de ce que je pensais que le serveur SQL "devrait juste faire darnit!", Mais je pensais que cela ne pouvait pas être fait. Ensuite, j'ai vu ça.
David Hay
54

Configuration de la table:

CREATE TABLE dbo.tbl (
    action VARCHAR(20) NOT NULL,
    view_edit VARCHAR(20) NOT NULL
);

INSERT INTO dbo.tbl (action, view_edit)
VALUES ('Action1', 'VIEW'),
       ('Action1', 'EDIT'),
       ('Action2', 'VIEW'),
       ('Action3', 'VIEW'),
       ('Action3', 'EDIT');

Ta table: SELECT action, view_edit FROM dbo.tbl

Ta table

Requête sans utiliser PIVOT:

SELECT Action, 
[View] = (Select view_edit FROM tbl WHERE t.action = action and view_edit = 'VIEW'),
[Edit] = (Select view_edit FROM tbl WHERE t.action = action and view_edit = 'EDIT')
FROM tbl t
GROUP BY Action

Requête utilisant PIVOT:

SELECT [Action], [View], [Edit] FROM
(SELECT [Action], view_edit FROM tbl) AS t1 
PIVOT (MAX(view_edit) FOR view_edit IN ([View], [Edit]) ) AS t2

Les deux requêtes résultent:
entrez la description de l'image ici

mxasim
la source
Merci pour cette réponse rare et claire. il montre immédiatement un exemple et les ensembles de données résultants
real_yggdrasil
Je sais que c'est vieux, mais c'est la démonstration de pivot la plus claire et la mieux illustrée que j'ai vue.
Stan Shaw
52

Si vous souhaitez spécifiquement utiliser la fonction SQL Server PIVOT, cela devrait fonctionner, en supposant que vos deux colonnes d'origine sont appelées act et cmd. (Pas si joli à regarder cependant.)

SELECT act AS 'Action', [View] as 'View', [Edit] as 'Edit'
FROM (
    SELECT act, cmd FROM data
) AS src
PIVOT (
    MAX(cmd) FOR cmd IN ([View], [Edit])
) AS pvt
Miles D
la source
6

Eh bien, pour votre échantillon et pour tous ceux avec un nombre limité de colonnes uniques, cela devrait le faire.

select 
    distinct a,
    (select distinct t2.b  from t t2  where t1.a=t2.a and t2.b='VIEW'),
    (select distinct t2.b from t t2  where t1.a=t2.a and t2.b='EDIT')
from t t1
vzczc
la source
5
With pivot_data as
(
select 
action, -- grouping column
view_edit -- spreading column
from tbl
)
select action, [view], [edit]
from   pivot_data
pivot  ( max(view_edit) for view_edit in ([view], [edit]) ) as p;
Vishwanath Dalvi
la source
0

J'avais une situation où j'analysais des chaînes et les deux premières positions de la chaîne en question correspondaient aux noms de champ d'une norme de codage des réclamations de soins de santé. Je supprimais donc les chaînes et obtiendrais des valeurs pour F4, UR et UQ ou autres. C'était génial sur un enregistrement ou quelques enregistrements pour un utilisateur. Mais quand je voulais voir des centaines d'enregistrements et les valeurs pour tous les utilisateurs, il fallait que ce soit un PIVOT. C'était merveilleux, surtout pour exporter beaucoup de disques pour exceller. La demande de rapport spécifique que j'avais reçue était "chaque fois qu'une personne a soumis une réclamation pour Benadryl, quelle valeur a-t-elle soumise dans les champs F4, UR et UQ. J'avais une APPLICATION EXTERNE qui a créé le ColTitle et les champs de valeur ci-dessous

PIVOT(
  min(value)
  FOR ColTitle in([F4], [UR], [UQ])
 )
1994Nerd
la source