2012-10-16 47 views
1

我有一个类似于以下内容的XML列;获取SQL中每个组的XML元素数

DECLARE @str AS VARCHAR(8000) 

SET @str = '<Root xmlns="http://myurl.com/services/" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> 
      <Notifications> 
       <Notification> 
        <NotificationDate>2012-08-16</NotificationDate> 
        <Scopes> 
        <NotificationScope> 
         <Code>a</Code> 
        </NotificationScope> 
        <NotificationScope> 
         <Code>b</Code> 
        </NotificationScope> 
        </Scopes> 
       </Notification> 
       <Notification> 
        <NotificationDate>2012-08-20</NotificationDate> 
        <Scopes> 
        <NotificationScope> 
         <Code>a</Code> 
        </NotificationScope> 
        </Scopes> 
       </Notification> 
      </Notifications></Root>' 

我希望能够获得每通知NotificationScope元素数的计数。例如,我正在寻找类似的东西;

Notification Date     Count 
2012-08-16       2 
2012-08-20       1 

事实上,在现实中,因为这数据是从数据库列得,我真的只返回那些与一个计数大于1

任何通知日期的记录感兴趣到目前为止,我设法提出的是以下内容,但这只是给了我一点数目;

declare @xmlvar XML; 
set @xmlvar = (SELECT cast(@str AS XML)) 
;WITH XMLNAMESPACES('http://myurl.com/services/' AS p) 
SELECT * FROM (
select @xmlvar.value('count(/p:Root/p:Notifications/p:Notification/p:Scopes/p:NotificationScope)', 'INT') AS 'NotificationScopeCount', 
     @xmlvar.value('count(/p:Root/p:Notifications/p:Notification/p:NotificationDate)', 'INT') AS 'NotificationDateCount' 
) a WHERE NotificationScopeCount > NotificationDateCount 

但理想情况下,我希望能够得到关联的日期也。请原谅我,如果这是一个可怕的方式去解决这个问题,我还没有在SQL中使用XML数据类型。

回答

1

你可以尝试使用这样的:

;WITH XMLNAMESPACES('http://myurl.com/services/' AS p) 
SELECT 
    NotificationDate = Notif.value('(p:NotificationDate)[1]', 'DATE'), 
    CodeCount = Notif.value('count(p:Scopes/p:NotificationScope/p:Code)', 'int') 
FROM 
    @xmlvar.nodes('/p:Root/p:Notifications/p:Notification') AS Tbl(Notif) 

给我的输出:

enter image description here

+0

感谢。 NotificationDate列中的[1]是否充当聚合类型的值? –

+0

@MrMoose:否,'[1]'只选择由该XPath定义的XML节点列表中的第一个(可能多个)条目。由于您的''节点只包含一个''(我认为是这样),所以您就是这么想的 - 从通知节点获取*通知日期。我的代码在这里没有进行任何聚合(如果你需要的话),你必须要聚合你自己(例如,把它包装到CTE中,然后在日期列上做一个GROUP BY) –

+1

非常好。感谢那。我已经检查了[你的问题](http://stackoverflow.com/questions/3685155/combine-cte-with-and-a-with-xmlnamespaces-in-sql-server)关于如何将cte和xmlnamespaces结合起来看看如何实现这:) –