J'en ai customer_comments
divisé en plusieurs lignes en raison de la conception de la base de données, et pour un rapport, je dois combiner le comments
de chaque unique id
en une seule ligne. J'ai déjà essayé quelque chose avec cette liste délimitée de la clause SELECT et de l' astuce COALESCE, mais je ne me souviens pas et je ne dois pas l'avoir enregistrée. Je n'arrive pas à le faire fonctionner dans ce cas non plus, semble seulement fonctionner sur une seule ligne.
Les données ressemblent à ceci:
id row_num customer_code comments
-----------------------------------
1 1 Dilbert Hard
1 2 Dilbert Worker
2 1 Wally Lazy
Mes résultats doivent ressembler à ceci:
id customer_code comments
------------------------------
1 Dilbert Hard Worker
2 Wally Lazy
Donc, pour chacun, row_num
il n'y a vraiment qu'une seule ligne de résultats; les commentaires doivent être combinés dans l'ordre de row_num
. L' SELECT
astuce liée ci-dessus fonctionne pour obtenir toutes les valeurs d'une requête spécifique sur une seule ligne, mais je ne sais pas comment la faire fonctionner dans le cadre d'une SELECT
instruction qui crache toutes ces lignes.
Ma requête doit parcourir toute la table seule et sortir ces lignes. Je ne les combine pas en plusieurs colonnes, une pour chaque ligne, donc PIVOT
cela ne semble pas applicable.
la source
order by
dans la sous-requête. C'est construire XML en utilisantfor xml
et c'est la façon de construire XML en utilisant TSQL. L'ordre des éléments dans un fichier XML est une question importante et peut être invoquée. Donc, si cette technique ne garantit pas l'ordre, la prise en charge XML dans TSQL est gravement endommagée.row_num desc
doit obéir à ceorder by
que Mikael a suggéré). Je vais supprimer les commentaires suggérant le contraire maintenant que la requête contient le droitorder by
et j'espère que @JonSeigel envisage de faire de même.Si vous êtes autorisé à utiliser CLR dans votre environnement, il s'agit d'un cas sur mesure pour un agrégat défini par l'utilisateur.
En particulier, c'est probablement la voie à suivre si les données source ne sont pas trivialement grandes et / ou si vous avez besoin de faire ce genre de choses beaucoup dans votre application. Je soupçonne fortement le plan de requête pour la solution d' Aaron pas bien à mesure que la taille d'entrée augmente. (J'ai essayé d'ajouter un index à la table temporaire, mais cela n'a pas aidé.)
Cette solution, comme bien d'autres choses, est un compromis:
EDIT: Eh bien, je suis allé essayer de voir si c'était vraiment mieux, et il s'avère que l'exigence que les commentaires soient dans un ordre spécifique n'est actuellement pas possible de satisfaire en utilisant une fonction d'agrégation. :(
Voir SqlUserDefinedAggregateAttribute.IsInvariantToOrder . Fondamentalement, ce que vous devez faire est
OVER(PARTITION BY customer_code ORDER BY row_num)
maisORDER BY
n'est pas pris en charge dans leOVER
clause lors de l'agrégation. Je suppose que l'ajout de cette fonctionnalité à SQL Server ouvre une boîte de vers, car ce qui devrait être modifié dans le plan d'exécution est trivial. Le lien susmentionné indique que cela est réservé pour une utilisation future, donc cela pourrait être implémenté à l'avenir (en 2005, vous n'avez probablement pas de chance, cependant).Cela pourrait encore être accompli en emballant et en analysant
row_num
valeur dans la chaîne agrégée, puis en effectuant le tri dans l'objet CLR ... ce qui semble assez hackish.Dans tous les cas, voici le code que j'ai utilisé au cas où quelqu'un d'autre trouverait cela utile même avec la limitation. Je vais laisser la partie de piratage comme un exercice pour le lecteur. Notez que j'ai utilisé AdventureWorks (2005) pour les données de test.
Assemblage d'agrégats:
T-SQL pour tester (
CREATE ASSEMBLY
, etsp_configure
pour activer CLR omis):la source
Voici une solution basée sur un curseur qui garantit l'ordre des commentaires par
row_num
. (Voir mon autre réponse pour savoir comment le[dbo].[Comments]
tableau a été rempli.)la source
la source