2012-10-16 86 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結合起來看看如何實現這:) –