按xml查询的结果进行分组

时间:2012-09-26 10:40:23

标签: sql xml tsql group-by sqlxml

我有一个带有XML列的表(称为MetaData),如下所示:

<props>
  <prop name="bytes" value="194" />
  <prop name="error" value="File is a text file" />
  <prop name="mime-type" value="text/plain " />
</props>

现在我有一些不同的错误,我可以在这里选择:

SELECT MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error,
       MetaData.value('(/props/prop[@name="mime-type"]/@value)[1]', 'varchar(50)') MimeType,
       *
FROM source
WHERE MetaData.exist('/props/prop[@name="error"]') = 1

现在我想计算错误的频率:

SELECT MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error,
       COUNT(*) Count
FROM source
WHERE MetaData.exist('/props/prop[@name="error"]') = 1
GROUP BY Error

但我收到错误消息:

  Meldung 207,Ebene 16,Status 1,Zeile 5
  UngültigerSpaltenname'错误'。

这意味着:无效的列名称'错误'

我也试过这个:

Select Error, COUNT(Error) FROM (
    SELECT MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error
    FROM videos
    WHERE MetaData.exist('/props/prop[@name="error"]') = 1
)
GROUP BY Error

但是崩溃了:

  Meldung 156,Ebene 15,Status 1,Zeile 6
  derNähedesGROUP-Schlüsselworts的Falsche Syntax。

这意味着:关键字GROUP

附近的语法错误

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:3)

ORDER BY子句中唯一可以在同一查询中引用别名列的时间。你最后一次尝试的错误是子查询必须被赋予一个表别名,我在下面用“X”来表示没有更好的名字。

SELECT Error, COUNT(Error) [Count]
FROM (
    SELECT MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error
    FROM source
    WHERE MetaData.exist('/props/prop[@name="error"]') = 1
) X
GROUP BY Error

而且Count是一个保留字,所以如果你要使用它,你需要在方括号中。

答案 1 :(得分:2)

在第二个查询中,您需要命名子查询

Select Error, COUNT(Error) FROM
( 
    SELECT MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error 
    FROM videos 
    WHERE MetaData.exist('/props/prop[@name="error"]') = 1 
) subqueryname
GROUP BY Error 

你可以给它几乎任何你喜欢的名字。

答案 2 :(得分:0)

正确。你也可以这样:

SELECT error, COUNT(*) errorCount
FROM
    (
    SELECT
        e.c.value ('@value', 'varchar(50)') Error
    FROM source s
        CROSS APPLY s.metadata.nodes('props/prop[@name="error"]') e(c) 
    ) x
GROUP BY error

您也可以使用XQuery执行此操作,但不清楚您希望预期结果的外观。试试这个:

DECLARE @source TABLE ( metadata XML )

INSERT INTO @source
SELECT '<props> 
  <prop name="bytes" value="194" /> 
  <prop name="error" value="File is a text file" /> 
  <prop name="mime-type" value="text/plain " /> 
</props>'

INSERT INTO @source
SELECT '<props> 
  <prop name="bytes" value="0" /> 
  <prop name="error" value="error 1" /> 
  <prop name="error" value="error 2" /> 
  <prop name="mime-type" value="text/plain " /> 
</props>'

SELECT
    MetaData.value('(/props/prop[@name="error"]/@value)[1]', 'varchar(50)') Error, 
    MetaData.value('(/props/prop[@name="mime-type"]/@value)[1]', 'varchar(50)') MimeType, 
    MetaData.value('count(/props/prop[@name="error"])', 'int') errorCount, 
    * 
FROM @source 
WHERE MetaData.exist('/props/prop[@name="error"]') = 1