2016-02-26 46 views
2

我將XML數據存儲在SQL Server數據庫中的一列中。XPATH查詢從存儲在SQL Server數據庫列中的XML中獲取數據

<data> 
    <row> 
<element name="product">Piston</element> 
<element name="number">1.2</element> 
    </row> 
<row> 
<element name="product">Piston Ring</element> 
<element name="number">2</element> 
    </row> 
<row> 
<element name="product">Piston</element> 
<element name="number">1.5</element> 
    </row> 
</data> 

有沒有一種方法可以得到以下格式的結果?

------------------------------ 
Product | Count 
------------------------------ 
Piston  | 2 
Piston Ring| 1 
------------------------------ 

我試圖使用XPath這給我算什麼,但如果我能按產品,然後得到一個數不知道。

我正在尋找類似的東西(在SQL查詢)

SELECT Product, Count(Product) FROM ABC 
GROUP BY Product 

回答

5

不能使用內GROUP BY直接的XML方法,所以我會使用一個CTE。首先,你得表數據從你的XML的,比你可以做一個 「正常」 COUNTGROUP BY

DECLARE @xml XML= 
'<data> 
    <row> 
    <element name="product">Piston</element> 
    <element name="number">1.2</element> 
    </row> 
    <row> 
    <element name="product">Piston Ring</element> 
    <element name="number">2</element> 
    </row> 
    <row> 
    <element name="product">Piston</element> 
    <element name="number">1.5</element> 
    </row> 
</data>'; 

;WITH MyRows AS 
(
    SELECT OneRow.value('(element[@name="product"])[1]','varchar(max)') AS Product 
    FROM @xml.nodes('/data/row') AS A(OneRow) 
) 
SELECT Product,COUNT(Product) AS [Count] 
FROM MyRows 
GROUP BY Product 
+0

嗨,這是給出了預期的結果,但花費了太多的時間。 (我檢查了非常大的數據)。但是,謝謝,它的作品。 – A3006

+0

@Anand,你可能會想到一個XML索引。我很快回答了類似的問題:http://stackoverflow.com/q/35575990/5089204 – Shnugo

+0

@Shnugo。你能解釋下面的工作原理嗎? SELECT OneRow.value('(element [@ name =「product」])[1]','varchar(max)')AS產品 從@ xml.nodes('/ data/row')AS A(OneRow) – Mark

0

我會用從tableCROSS APPLY到XML列

CREATE TABLE XMLwithOpenXML (
    id INT IDENTITY PRIMARY KEY 
    , XMLData XML 
    , LoadedDateTime DATETIME 
) 
GO 

DECLARE @xml XML = ' 
<data> 
    <row> 
     <element name="product">Piston</element> 
     <element name="number">1.2</element> 
    </row> 
    <row> 
     <element name="product">Piston Ring</element> 
     <element name="number">2</element> 
    </row> 
    <row> 
     <element name="product">Piston</element> 
     <element name="number">1.5</element> 
    </row> 
</data>' 

INSERT INTO XMLwithOpenXML (XMLData, LoadedDateTime) 
SELECT @xml, GETDATE() 

SELECT Product, COUNT(Product) AS ProdCount 
FROM (
    SELECT 
     n.C.value('(element[@name="product"])[1]', 'varchar(100)') product 
     , n.C.value('(element[@name="number"])[1]', 'varchar(100)') number 
    FROM XMLwithOpenXML 
    CROSS APPLY XMLData.nodes('/data/row') n(C) 
) A 
GROUP BY Product 
1
DECLARE @x XML= 
'<data> 
    <row> 
    <element name="product">Piston</element> 
    <element name="number">1.2</element> 
    </row> 
    <row> 
    <element name="product">Piston Ring</element> 
    <element name="number">2</element> 
    </row> 
    <row> 
    <element name="product">Piston</element> 
    <element name="number">1.5</element> 
    </row> 
</data>' 

SELECT val, COUNT_BIG(1) 
FROM (
    SELECT val = t.c.value('.', 'VARCHAR(100)') 
    FROM @x.nodes('/data/row/element[@name="product"]') t(c) 
) t 
GROUP BY val 
OPTION (OPTIMIZE FOR (@x = NULL)) 

輸出 -

------------------- -------------------- 
Piston    2 
Piston Ring   1 
+0

這真是太棒了!謝謝。你能解釋我最後一行嗎? 「OPTION(OPTIMIZE FOR(@x = NULL))」 – A3006

+0

只是一個小的優化問題,如果你期望一個非常大的XML – Devart

相關問題