Ok, je sens que je dois sauter pour commenter au sujet How do you concat multiple rows into one column in SQL Server? et de fournir une réponse plus préférée. Je suis vraiment désolé, mais l'utilisation de fonctions à valeur scalaire comme celle-ci va tuer les performances. Ouvrez SQL Profiler et regardez ce qui se passe lorsque vous utilisez une fonction scalaire qui appelle une table.
De plus, la technique de mise à jour d'une variable pour la concaténation n'est pas encouragée car cette fonctionnalité pourrait ne pas continuer dans les futures versions.
La méthode préférée de concaténation de chaînes pour utiliser FOR XML PATH à la place.
select
stuff((select ', ' + t.tag from tags t where t.photoid = p.photoid order by tag for xml path('')),1,2,'') as taglist
,*
from photos
order by photoid;
Pour des exemples de la façon dont pour les travaux XML PATH, considérez ce qui suit, en imaginant que vous avez une table avec deux champs appelés 'id' et 'nom'
SELECT id, name
FROM table
order by name
FOR XML PATH('item'),root('itemlist')
;
donne:
<itemlist><item><id>2</id><name>Aardvark</a></item><item><id>1</id><name>Zebra</name></item></itemlist>
Mais si vous omettez la racine, vous obtenez quelque chose de légèrement différent:
SELECT id, name
FROM table
order by name
FOR XML PATH('item')
;
<item><id>2</id><name>Aardvark</a></item><item><id>1</id><name>Zebra</name></item>
Et si vous mettez une chaîne de chemin vide, vous obtenez encore plus proche de la concaténation de chaîne ordinaire:
SELECT id, name
FROM table
order by name
FOR XML PATH('')
;
<id>2</id><name>Aardvark</a><id>1</id><name>Zebra</name>
est maintenant le peu vraiment difficile ... Si vous nommez une colonne en commençant par un signe @, il devient un attribut, et si une colonne ne dispose pas d'un nom (ou vous l'appelez [*]), il laisse à cette étiquette aussi:
SELECT ',' + name
FROM table
order by name
FOR XML PATH('')
;
,Aardvark,Zebra
maintenant, enfin, à dépouiller la virgule de premier plan, la commande STUFF entre. STUFF (s, x, n, s2) enlève n caractères de s, en commençant à la position x. À leur place, ça met s2.Donc:
SELECT STUFF ('abcde', 2,3, '123456');
donne:
a123456e
ont donc maintenant un coup d'œil à ma requête ci-dessus pour votre taglist.
select
stuff((select ', ' + t.tag from tags t where t.photoid = p.photoid order by tag for xml path('')),1,2,'') as taglist
,*
from photos
order by photoid;
Pour chaque photo, j'ai une sous-requête qui saisit les balises et les concaténer (dans l'ordre) avec un commma et un espace. Ensuite, j'entoure cette sous-requête dans une commande stuff pour supprimer la virgule et l'espace.
Je m'excuse pour les fautes de frappe - Je n'ai pas créé les tables sur ma propre machine pour le tester.
Rob
est qu'une "ligne", "valeur table", ou la fonction "valeur scalaire"? ce sont les options VS me donne ... – Jason
Scalar Valued - désolé je n'ai pas précisé. – Eric
Elaboration d'un bit: les fonctions Table et Inline renvoient toutes deux une table de type. Ces options sont pour vous aider avec une partie de la syntaxe, mais si vous avez exécuté ce SQL directement, ce serait automatiquement scalaire. – Eric