J'ai été chargé de trouver un moyen de traduire les données suivantes:
date category amount
1/1/2012 ABC 1000.00
2/1/2012 DEF 500.00
2/1/2012 GHI 800.00
2/10/2012 DEF 700.00
3/1/2012 ABC 1100.00
dans ce qui suit:
date ABC DEF GHI
1/1/2012 1000.00
2/1/2012 500.00
2/1/2012 800.00
2/10/2012 700.00
3/1/2012 1100.00
Les espaces vides peuvent être des valeurs NULL ou des espaces vides, que ce soit bien, et les catégories devraient être dynamiques. Une autre mise en garde possible est que nous exécuterons la requête dans une capacité limitée, ce qui signifie que les tables temporaires sont épuisées. J'ai essayé de faire des recherches et j'ai atterri, PIVOT
mais comme je ne l'ai jamais utilisé auparavant, je ne le comprends vraiment pas, malgré tous mes efforts pour le comprendre. Est-ce que quelqu'un peut-il me montrer la bonne direction?
sql
sql-server
tsql
pivot
Sean Cunningham
la source
la source
Réponses:
PIVOT SQL dynamique:
Résultats:
la source
@cols
vous pouvez le supprimerDISTINCT
et l'utiliserGROUP BY
etORDER BY
lorsque vous obtenez la liste de@cols
.PIVOT SQL dynamique
Approche différente pour créer une chaîne de colonnes
Résultat
la source
Je sais que cette question est plus ancienne mais je cherchais à travers les réponses et pensais que je pourrais être en mesure d'étendre la partie "dynamique" du problème et éventuellement aider quelqu'un.
Tout d'abord, j'ai conçu cette solution pour résoudre un problème que deux collègues rencontraient avec des ensembles de données inconstants et volumineux devant être pivotés rapidement.
Cette solution nécessite la création d'une procédure stockée, donc si cela est hors de question pour vos besoins, veuillez arrêter de lire maintenant.
Cette procédure va prendre les variables clés d'une instruction pivot pour créer dynamiquement des instructions pivot pour différents tableaux, noms de colonnes et agrégats. La colonne statique est utilisée comme colonne de regroupement par / identité pour le pivot (cela peut être supprimé du code si ce n'est pas nécessaire mais est assez courant dans les instructions pivot et était nécessaire pour résoudre le problème d'origine), la colonne pivot est l'endroit où le les noms de colonne résultants finaux seront générés à partir de, et la colonne de valeur sera celle à laquelle l'agrégat sera appliqué. Le paramètre Table est le nom de la table, y compris le schéma (schema.tablename), cette partie du code pourrait utiliser un peu d'amour car elle n'est pas aussi propre que je le souhaiterais. Cela a fonctionné pour moi car mon utilisation n'était pas publique et l'injection SQL n'était pas un problème.
Commençons par le code pour créer la procédure stockée. Ce code devrait fonctionner dans toutes les versions de SSMS 2005 et supérieur mais je ne l'ai pas testé en 2005 ou 2016 mais je ne vois pas pourquoi cela ne fonctionnerait pas.
Ensuite, nous préparerons nos données pour l'exemple. J'ai pris l'exemple de données de la réponse acceptée avec l'ajout de quelques éléments de données à utiliser dans cette preuve de concept pour montrer les sorties variées du changement global.
Les exemples suivants montrent les instructions d'exécution variées montrant les agrégats variés comme exemple simple. Je n'ai pas choisi de modifier les colonnes statique, pivot et valeur pour garder l'exemple simple. Vous devriez pouvoir simplement copier et coller le code pour commencer à jouer avec lui-même
Cette exécution renvoie respectivement les ensembles de données suivants.
la source
Version mise à jour pour SQL Server 2017 à l'aide de la fonction STRING_AGG pour construire la liste des colonnes pivotantes:
la source
Vous pouvez y parvenir en utilisant TSQL dynamique (n'oubliez pas d'utiliser QUOTENAME pour éviter les attaques par injection SQL):
Pivots avec colonnes dynamiques dans SQL Server 2005
SQL Server - Table PIVOT dynamique - Injection SQL
Référence obligatoire à The Curse and Blessings of Dynamic SQL
la source
QUOTENAME
n'aide les attaques par injection SQL que si vous acceptez @tableName comme paramètre d'un utilisateur et que vous l'ajoutez à une requête commeSET @sql = 'SELECT * FROM ' + @tableName;
. Vous pouvez créer de nombreuses chaînes SQL dynamiques vulnérables etQUOTENAME
ne faites rien pour vous aider.Il y a ma solution pour nettoyer les valeurs nulles inutiles
la source
Le code ci-dessous fournit les résultats qui remplacent NULL à zéro dans la sortie.
Création de table et insertion de données:
Requête pour générer les résultats exacts qui remplacent également NULL par des zéros:
PRODUCTION :
la source