我已经尝试了与此主题相关的SO线程的所有建议,但仍然没有得到我需要的东西。我有一个名为SC
的XML列。这是在SQL Server 2014上(如果它很重要)。表格中只有一行,而SC
列中的XML数据包含以下代码段...
<SC_ROOT>
<COMPONENTS>
<COMPONENT>
<NAME>Status A Detection</NAME>
<PROPERTIES>
<COMP_ENABLED>True</COMP_ENABLED>
</PROPERTIES>
</COMPONENT>
...
</COMPONENTS>
</SC_ROOT>
我想仅返回<NAME>
和<COMP_ENABLED>
的表格,仅用于<NAME>
包含“检测”的项目。如果已经有一个很好的例子请指点我吗?提前谢谢!
答案 0 :(得分:4)
试试这个:
SELECT
Name = xc.value('(NAME)[1]', 'varchar(50)'),
CompEnabled = xc.value('(PROPERTIES/COMP_ENABLED)[1]', 'varchar(10)')
FROM
dbo.YourTable
CROSS APPLY
SC.nodes('/SC_ROOT/COMPONENTS/COMPONENT') AS XT(XC)
WHERE
xc.value('(NAME)[1]', 'varchar(50)') LIKE '%Detection'
.nodes()
调用基本上返回一个“虚拟表”,其表别名为XT
,其中包含一列(别名XC
),其中包含与XPath表达式对应的XML片段 - 基本上是<COMPONENT>
XML片段。您可以深入了解所需的详细信息
更新:如果你的XML看起来像这样:
<COMPONENT>
<NAME>Status A Detection</NAME>
<PROPERTIES NAME="COMP_ENABLED" VALUE="True" />
</COMPONENT>
然后使用此代码获取结果:
SELECT
Name = xc.value('(NAME)[1]', 'varchar(50)'),
CompEnabled = xc.value('(PROPERTIES[@NAME="COMP_ENABLED"]/@VALUE)[1]', 'varchar(10)')
FROM
dbo.YourTable
CROSS APPLY
SC.nodes('/SC_ROOT/COMPONENTS/COMPONENT') AS XT(XC)
WHERE
xc.value('(NAME)[1]', 'varchar(50)') LIKE '%Detection'
答案 1 :(得分:2)
因此,假设COMPONENT
可以重复,并且您只想选择COMPONENT
NAME LIKE '%Detection%'
个节点,则以下内容应该有效:
DECLARE @xml xml = '<SC_ROOT>
<COMPONENTS>
<COMPONENT>
<NAME>Status A Detection</NAME>
<PROPERTIES>
<COMP_ENABLED>True</COMP_ENABLED>
</PROPERTIES>
</COMPONENT>
<COMPONENT>
<NAME>Status B Other</NAME>
<PROPERTIES>
<COMP_ENABLED>True</COMP_ENABLED>
</PROPERTIES>
</COMPONENT>
<COMPONENT>
<NAME>Status C Detection</NAME>
<PROPERTIES>
<COMP_ENABLED>True</COMP_ENABLED>
</PROPERTIES>
</COMPONENT>
</COMPONENTS>
</SC_ROOT>'
SELECT X.Component.query('.')
FROM @xml.nodes('/SC_ROOT/COMPONENTS/COMPONENT') as X(Component)
WHERE CAST(x.Component.query('NAME/text()') AS NVARCHAR(100)) LIKE '%Detection%'
输出:
<COMPONENT><NAME>Status A Detection</NAME><PROPERTIES><COMP_ENABLED>True</COMP_ENABLED></PROPERTIES></COMPONENT>
<COMPONENT><NAME>Status C Detection</NAME><PROPERTIES><COMP_ENABLED>True</COMP_ENABLED></PROPERTIES></COMPONENT>
这将为您提供原始XML片段。如果您想将其粉碎到表格,则必须修改您选择的列以及.query()
中的SELECT
。只要至少有一个NAME
中包含单词COMPONENT
,无论'Detection'
在NAME
中重复多少次,这都会有效。
如果SELECT X.Component.query('.')
FROM @xml.nodes('/SC_ROOT/COMPONENTS/COMPONENT[contains(NAME[1], "Detection")]') as X(Component)
只能出现一次,或者您只关心第一个实例,那么您也可以这样做:
SELECT
DATEPART(yyyy, ce.DueDate) AS year,
DATEPART(mm, ce.DueDate) AS Month,
COUNT(CASE WHEN rt.Code = 'Pass' THEN 1 ELSE NULL END) AS NumPass,
COUNT(CASE WHEN rt.Code = 'Fail' THEN 1 ELSE NULL END) AS NumFail
FROM
ControlEvent ce
INNER JOIN
ProcessEvent pe ON pe.ControlEventId = ce.Id
INNER JOIN
ResultType rt ON pe.ResultTypeId = rt.Id
WHERE
DATEDIFF(dd,ce.DueDate,GETDATE()) <= 0
AND DATEDIFF(dd,ce.DueDate,DATEADD(mm, 3, GETDATE())) >= 0
AND pe.ProcessId = 1040
GROUP BY
DATEPART(yyyy, ce.DueDate), DATEPART(mm, ce.DueDate)
ORDER BY
DATEPART(yyyy, ce.DueDate), DATEPART(mm, ce.DueDate)
哪个会产生相同的输出。