Comment append un type de données XML dans une clause GROUP BY?

Je crée un forum, j'ai donc créé une table avec des posts. L'un des champs est un Body avec le type XML . Maintenant, je voudrais créer une requête qui renvoie tous les messages et le nombre d'enfants de chaque post. Je fais cela avec une fonction d'agrégat. J'ai besoin d'utiliser un groupe lorsque j'utilise la fonction agrégée. Lorsque j'utilise le champ dans le group by , j'obtiens l'exception suivante:

Le type de données XML ne peut pas être comparé ou sortingé, sauf lors de l'utilisation de l'opérateur IS NULL.

Comment puis-je resoudre ceci?

Ma question est:

 SELECT Post.PostId, Post.[Body], Count(Children.PostId) FROM dbo.Post Post, dbo.Post Children WHERE Children.ParentId = Post.PostId GROUP BY Post.PostId, Post.[Body] 

Vous pouvez faire l'agrégation dans un CTE puis vous joindre à cela

 WITH Children(Cnt, ParentId) AS (SELECT COUNT(*), ParentId FROM dbo.Post GROUP BY ParentId) SELECT P.PostId, P.[Body], ISNULL(Cnt, 0) AS Cnt FROM dbo.Post P LEFT JOIN Children /*To include childless posts*/ ON Children.ParentId = P.PostId ORDER BY P.PostId 

Pouvez-vous faire le Group par sans sélectionner le champ XML, dans une sous-requête, puis select le champ XML, et les autres colonnes se joignant à votre sous-requête?

En utilisant votre requête, vous obtiendrez: par exemple

 SELECT Post.[Body], sq.* FROM ( SELECT Post.PostId, Count(Children.PostId) FROM dbo.Post Post, dbo.Post Children WHERE Children.ParentId = Post.PostId GROUP BY Post.PostId ) as sq INNER JOIN Post on Post.PostId= sq.PostId 

Cependant, vous utilisez une jointure join / ansi ici, ce qui n'est pas la meilleure façon de le faire. Une meilleure façon serait:

 SELECT Post.[Body], sq.* FROM ( SELECT Post.PostId, Count(Children.PostId) FROM dbo.Post Post LEFT OUTER JOIN Children on Children.ParentId = Post.PostId GROUP BY Post.PostId ) as sq INNER JOIN Post on Post.PostId= sq.PostId 

essayer de cette façon espère que cela vous aidera

 SELECT Post.PostId, Post.[Body], Count(Children.PostId) over() as totalids FROM dbo.Post Post, dbo.Post Children WHERE Children.ParentId = Post.PostId 

comme j'ai travaillé vérifier ceci

  create table xmltable (attr1 int identity ,attr2 varchar(50),attr3 xml) insert into xmltable select 'i',(SELECT ( SELECT 'sometext' FOR XML PATH('body'),TYPE)FOR XML PATH(''),ROOT('SampleXML')) union all select 'j',(SELECT ( SELECT 'sometext' FOR XML PATH('body'),TYPE)FOR XML PATH(''),ROOT('SampleXML')) union all select 'k',(SELECT ( SELECT 'sometext' FOR XML PATH('body'),TYPE)FOR XML PATH(''),ROOT('SampleXML')) union all select 'l',(SELECT ( SELECT 'sometext' FOR XML PATH('body'),TYPE)FOR XML PATH(''),ROOT('SampleXML')) create table xmlid (x int ,y varchar(50)) insert into xmlid select 1,'x' union all select 1,'y' union all select 2,'z' union all select 2,'xyz1' union all select 3,'xyz2' union all select 1,'xyz3' select * from xmltable select * from xmlid 

créer des tables puis

 select * from xmltable select * from xmlid select attr1,attr2, attr3,count(attr1) over(partition by attr2 ) as total_qtyover from xmltable a,xmlid b where a.attr1=bx 

voir aussi ceci Comment aggréger sans utiliser "GROUP BY"?

Je décomposerais en deux requêtes, une pour get les identifiants et les counts d'enfants, et une autre pour get les corps. Pour effectuer un GROUP BY le server doit sortinger les champs de regroupement. Vous pouvez donc déplacer et comparer un grand nombre de données lorsque vous n'en avez pas besoin (à less que vous n'ayez plusieurs corps de post avec le même ID).