SQL XML 基于XML 节点聚合函数的列过滤器
SQL XML Column filter based on XML node aggregate function
我有如下 XML 列
<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
<dateReported>1/1/2001<dateReported>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
<dateReported>1/1/2014<dateReported>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
<dateReported>1/1/2012<dateReported>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
<dateReported>1/1/2011<dateReported>
</AAA></x>
<BB><ID>12</ID><BB>
<CC><Type>XML</Type></CC>
</XMLDoc>
我需要获取最多 dateReported 的名称和值节点。到目前为止,我的 sQL 如下所示
SELECT
Col1 = Col.value('(/XMLDoc/x/AAA/Name)[1]', 'varchar(255)'),
Col2 = Col.value('(/XMLDoc/x/AAA/Value)[2]', 'varchar(255)'),
Col3 = Col.value('(/XMLDoc/BB/ID)[1]', 'varchar(255)'),
Col4 = Col.value('(/XMLDoc/CC/Type)[1]', 'varchar(255)')
FROM
table t
基本上我需要输出为 Name_B
、Val_B
、12
、XML
,因为 AAA 的 datereported
具有最大值。
您可以尝试这样的操作 - 设置一个 CTE(通用 Table 表达式)以 "extract" 将 XML 值转换为关系格式,然后执行简单的 SELECT
在该结果集上:
;WITH XmlCTE AS
(
SELECT
ID,
Name = XC.value('(Name)[1]', 'varchar(100)'),
Value = XC.value('(Value)[1]', 'varchar(100)'),
DateReported = XC.value('(dateReported)[1]', 'datetime')
BB_ID = YourXmlColumn.value('(/XMLDoc/BB/ID)[1]', 'int'),
CC_Type = YourXmlColumn.value('(/XMLDoc/CC/Type)[1]', 'varchar(50)')
FROM
dbo.YourTable
CROSS APPLY
YourXmlColumn.nodes('/XMLDoc/AAA') AS XT(XC)
)
SELECT *
FROM XmlCTE
WHERE DateReported = (SELECT MAX(DateReported) FROM XmlCTE)
在这种情况下可以使用以下SQL XML query
with cte as (
SELECT
t.id,
name.value('.','nvarchar(50)') as names,
dates.value('.','nvarchar(50)') as dates
FROM t
CROSS APPLY Col.nodes('/XMLDoc/AAA') as XMLtable1(AAA)
CROSS APPLY XMLtable1.AAA.nodes('Name') as XMLtable2(name)
CROSS APPLY XMLtable1.AAA.nodes('dateReported') as XMLtable3(dates)
)
select *
from (
select
*,
rn = ROW_NUMBER() over (partition by id order by dates desc)
from cte
) t where rn = 1
对于更新后的要求,关注SQL Server XML query可以提供帮助
请测试 table 中超过一行的查询以获得更准确的测试结果
;with cte as (
SELECT
t.id,
b.value('.','nvarchar(500)') as bbid,
c.value('.','nvarchar(500)') as cc,
name.value('.','nvarchar(50)') as names,
dates.value('.','nvarchar(50)') as dates
FROM t
CROSS APPLY Col.nodes('/XMLDoc/BB/ID') as XMLtable4(b)
CROSS APPLY Col.nodes('/XMLDoc/CC') as XMLtable5(c)
CROSS APPLY Col.nodes('/XMLDoc/x') as XMLtable0(d)
CROSS APPLY XMLtable0.d.nodes('AAA') as XMLtable1(AAA)
CROSS APPLY XMLtable1.AAA.nodes('Name') as XMLtable2(name)
CROSS APPLY XMLtable1.AAA.nodes('dateReported') as XMLtable3(dates)
)
select *
from (
select
*,
rn = ROW_NUMBER() over (partition by id order by dates desc)
from cte
) t where rn = 1
我有如下 XML 列
<XMLDoc>
<AAA>
<Name>Name_A</Name>
<Value>Val_A</Value>
<dateReported>1/1/2001<dateReported>
</AAA>
<AAA>
<Name>Name_B</Name>
<Value>Val_B</Value>
<dateReported>1/1/2014<dateReported>
</AAA>
<AAA>
<Name>Name_C</Name>
<Value>Val_C</Value>
<dateReported>1/1/2012<dateReported>
</AAA>
<AAA>
<Name>Name_D</Name>
<Value>Val_D</Value>
<dateReported>1/1/2011<dateReported>
</AAA></x>
<BB><ID>12</ID><BB>
<CC><Type>XML</Type></CC>
</XMLDoc>
我需要获取最多 dateReported 的名称和值节点。到目前为止,我的 sQL 如下所示
SELECT
Col1 = Col.value('(/XMLDoc/x/AAA/Name)[1]', 'varchar(255)'),
Col2 = Col.value('(/XMLDoc/x/AAA/Value)[2]', 'varchar(255)'),
Col3 = Col.value('(/XMLDoc/BB/ID)[1]', 'varchar(255)'),
Col4 = Col.value('(/XMLDoc/CC/Type)[1]', 'varchar(255)')
FROM
table t
基本上我需要输出为 Name_B
、Val_B
、12
、XML
,因为 AAA 的 datereported
具有最大值。
您可以尝试这样的操作 - 设置一个 CTE(通用 Table 表达式)以 "extract" 将 XML 值转换为关系格式,然后执行简单的 SELECT
在该结果集上:
;WITH XmlCTE AS
(
SELECT
ID,
Name = XC.value('(Name)[1]', 'varchar(100)'),
Value = XC.value('(Value)[1]', 'varchar(100)'),
DateReported = XC.value('(dateReported)[1]', 'datetime')
BB_ID = YourXmlColumn.value('(/XMLDoc/BB/ID)[1]', 'int'),
CC_Type = YourXmlColumn.value('(/XMLDoc/CC/Type)[1]', 'varchar(50)')
FROM
dbo.YourTable
CROSS APPLY
YourXmlColumn.nodes('/XMLDoc/AAA') AS XT(XC)
)
SELECT *
FROM XmlCTE
WHERE DateReported = (SELECT MAX(DateReported) FROM XmlCTE)
在这种情况下可以使用以下SQL XML query
with cte as (
SELECT
t.id,
name.value('.','nvarchar(50)') as names,
dates.value('.','nvarchar(50)') as dates
FROM t
CROSS APPLY Col.nodes('/XMLDoc/AAA') as XMLtable1(AAA)
CROSS APPLY XMLtable1.AAA.nodes('Name') as XMLtable2(name)
CROSS APPLY XMLtable1.AAA.nodes('dateReported') as XMLtable3(dates)
)
select *
from (
select
*,
rn = ROW_NUMBER() over (partition by id order by dates desc)
from cte
) t where rn = 1
对于更新后的要求,关注SQL Server XML query可以提供帮助 请测试 table 中超过一行的查询以获得更准确的测试结果
;with cte as (
SELECT
t.id,
b.value('.','nvarchar(500)') as bbid,
c.value('.','nvarchar(500)') as cc,
name.value('.','nvarchar(50)') as names,
dates.value('.','nvarchar(50)') as dates
FROM t
CROSS APPLY Col.nodes('/XMLDoc/BB/ID') as XMLtable4(b)
CROSS APPLY Col.nodes('/XMLDoc/CC') as XMLtable5(c)
CROSS APPLY Col.nodes('/XMLDoc/x') as XMLtable0(d)
CROSS APPLY XMLtable0.d.nodes('AAA') as XMLtable1(AAA)
CROSS APPLY XMLtable1.AAA.nodes('Name') as XMLtable2(name)
CROSS APPLY XMLtable1.AAA.nodes('dateReported') as XMLtable3(dates)
)
select *
from (
select
*,
rn = ROW_NUMBER() over (partition by id order by dates desc)
from cte
) t where rn = 1