C# XPATH查询从存储在SQL Server DB列中的XML获取数据

C# XPATH查询从存储在SQL Server DB列中的XML获取数据,c#,sql-server,xml,tsql,xpath,C#,Sql Server,Xml,Tsql,Xpath,我将XML数据存储在SQLServer数据库中的一列中 <data> <row> <element name="product">Piston</element> <element name="number">1.2</element> </row> <row> <element name="product">Piston Ring</element> <

我将XML数据存储在SQLServer数据库中的一列中

<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>
我尝试使用Xpath,它可以为我提供任何计数,但不确定是否可以按产品分组,然后获得计数

我正在寻找类似于SQL查询的东西

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

您不能直接在groupbyso中使用XML方法,因此我将使用CTE。首先从XML中获取表数据,然后使用GROUP BY进行正常计数:

我将使用从表到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

您好,这给出了预期的结果,但是花费了太多的时间。我检查了大量数据。但是谢谢,它可以工作。@Anand,您可以考虑使用XML索引。我很快回答了一个类似的问题:@Shnugo。你能解释一下下面的工作原理吗?选择OneRow.value'element[@name=product][1],'varcharmax'作为产品,从@xml.nodes'/data/row'作为aonerow这太棒了!谢谢你能给我解释一下最后一行吗?选项OPTION OPTIMIZE FOR@x=null如果您希望有一个非常大的xml,那么这只是一个小的优化问题
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
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
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