Как добавить тип данных XML в предложении GROUP BY? - PullRequest
3 голосов
/ 23 декабря 2011

Я создаю форум, поэтому я создал таблицу с сообщениями.Одним из полей является Body с типом XML.Теперь я хотел бы создать запрос, который возвращает все сообщения и количество дочерних элементов каждого сообщения.Я делаю это с помощью агрегатной функции.Мне нужно использовать группу, когда я использую агрегатную функцию.Когда я использую поле в group by, я получу следующее исключение:

Тип данных XML нельзя сравнивать или сортировать, кроме случаев использования оператора IS NULL.1008 *

Как мне решить эту проблему?

Мой запрос:

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]

Ответы [ 4 ]

5 голосов
/ 23 декабря 2011

Вы можете выполнить агрегирование в CTE, а затем присоединиться к этому

.
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  
0 голосов
/ 23 декабря 2011

Я бы разбил его на два запроса: один для получения идентификаторов и количества детей, а другой - для получения тел.Выполнение GROUP BY требует от сервера сортировки по группирующим полям, поэтому вы можете перемещать и сравнивать большое количество данных, когда вам это не нужно (если только у вас нет нескольких тел сообщений с одинаковым идентификатором).

0 голосов
/ 23 декабря 2011

попробуйте так, надеюсь, вам это поможет

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

как я работал, проверьте это

 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

создать таблицы, затем

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=b.x

также смотрите это Как агрегировать без использования `GROUP BY`?

0 голосов
/ 23 декабря 2011

Можете ли вы сделать Группу, не выделив поле XML в подзапросе, затем выбрав поле XML и другие столбцы, присоединяющиеся к вашему подзапросу?

Используя ваш запрос, вы получите:например,

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

Однако здесь вы используете перекрестное соединение / анси, что не лучший способ сделать это.Лучше было бы:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...