Vous recherchez une solution élégante (ou toute autre) pour convertir des colonnes en lignes.
Voici un exemple: j'ai une table avec le schéma suivant:
[ID] [EntityID] [Indicator1] [Indicator2] [Indicator3] ... [Indicator150]
Voici ce que je souhaite obtenir comme résultat:
[ID] [EntityId] [IndicatorName] [IndicatorValue]
Et les valeurs de résultat seront:
1 1 'Indicator1' 'Value of Indicator 1 for entity 1'
2 1 'Indicator2' 'Value of Indicator 2 for entity 1'
3 1 'Indicator3' 'Value of Indicator 3 for entity 1'
4 2 'Indicator1' 'Value of Indicator 1 for entity 2'
Etc..
Est-ce que ça a du sens? Avez-vous des suggestions sur où chercher et comment le faire dans T-SQL?
sql
sql-server
tsql
unpivot
Sergueï
la source
la source
Réponses:
Vous pouvez utiliser la fonction UNPIVOT pour convertir les colonnes en lignes:
Notez que les types de données des colonnes que vous annulez doivent être les mêmes, vous devrez peut-être convertir les types de données avant d'appliquer le pivotement.
Vous pouvez également utiliser
CROSS APPLY
avec UNION ALL pour convertir les colonnes:Selon votre version de SQL Server, vous pouvez même utiliser CROSS APPLY avec la clause VALUES:
Enfin, si vous avez 150 colonnes à décompresser et que vous ne souhaitez pas coder en dur la requête entière, vous pouvez générer l'instruction SQL à l'aide de SQL dynamique:
la source
UNPIVOT
et / vs.APPLY
, ce billet de blog 2010 de Brad Schulz (et la suite ) est (sont) magnifique.Eh bien, si vous avez 150 colonnes, je pense que UNPIVOT n'est pas une option. Vous pouvez donc utiliser une astuce xml
sql fiddle demo
Vous pouvez également écrire du SQL dynamique, mais j'aime davantage le XML - pour le SQL dynamique, vous devez avoir les autorisations pour sélectionner des données directement à partir de la table et ce n'est pas toujours une option.
MISE
À JOUR Comme il y a une grande flamme dans les commentaires, je pense que je vais ajouter quelques avantages et inconvénients de xml / SQL dynamique. J'essaierai d'être aussi objectif que possible et de ne pas mentionner l'élégance et la laideur. Si vous avez d'autres avantages et inconvénients, modifiez la réponse ou écrivez dans les commentaires
les inconvénients
avantages
inserted
etdeleted
tables à l'intérieur de votre déclencheur (pas possible du tout avec dynamique);la source
Juste pour aider les nouveaux lecteurs, j'ai créé un exemple pour mieux comprendre la réponse de @ bluefeet à propos d'UNPIVOT.
la source
J'avais besoin d'une solution pour convertir des colonnes en lignes dans Microsoft SQL Server, sans connaître les noms de colonne (utilisés dans le déclencheur) et sans SQL dynamique (SQL dynamique est trop lent pour être utilisé dans un déclencheur).
J'ai finalement trouvé cette solution, qui fonctionne très bien:
Comme vous pouvez le voir, je convertis la ligne en XML (sous-requête sélectionnez i, * pour xml raw, cela convertit toutes les colonnes en une colonne xml)
Ensuite, j'APPLIQUE une fonction à chaque attribut XML de cette colonne, de sorte que j'obtienne une ligne par attribut.
Dans l'ensemble, cela convertit les colonnes en lignes, sans connaître les noms de colonne et sans utiliser SQL dynamique. C'est assez rapide pour mon objectif.
(Edit: je viens de voir la réponse de Roman Pekar ci-dessus, qui fait la même chose. J'ai d'abord utilisé le déclencheur SQL dynamique avec les curseurs, qui était 10 à 100 fois plus lent que cette solution, mais peut-être que cela a été causé par le curseur, pas par le SQL dynamique. Quoi qu'il en soit, cette solution est très simple et universelle, donc c'est définitivement une option).
Je laisse ce commentaire à cet endroit, car je souhaite faire référence à cette explication dans mon article sur le déclencheur d'audit complet, que vous pouvez trouver ici: https://stackoverflow.com/a/43800286/4160788
la source
Vous pouvez obtenir la liste des tables dont le nombre de lignes est supérieur à 350. Vous pouvez voir la liste des solutions de la table sous forme de ligne.
la source
Juste parce que je ne l'ai pas vu mentionné.
Si 2016+, voici encore une autre option pour décompresser dynamiquement les données sans réellement utiliser Dynamic SQL.
Exemple
Retour
la source