在 SQL Server XML 列中,如何验证相同的值是不是存在于多行中
Posted
技术标签:
【中文标题】在 SQL Server XML 列中,如何验证相同的值是不是存在于多行中【英文标题】:In SQL Server XML column how do I verify whether same value is present in more than one rows or not在 SQL Server XML 列中,如何验证相同的值是否存在于多行中 【发布时间】:2021-03-10 17:40:12 【问题描述】:在 SQL Server XML 列中,如何验证相同的值是否存在于多行中?
值可以是动态的 - 它不是固定的。请参考下表,其中 Id 列为主键,ExtendedData 列中的 Tag 值可能超过 1 行。
查询INSERT记录到表中
DECLARE @Table1 TABLE (Id BIGINT, AccountNumber int,ExtendedData XML)
INSERT INTO @Table1 (Id,AccountNumber,ExtendedData) VALUES
(1, 14, '<ExtendedData> <Data> <POLICYNBR>131313</POLICYNBR> <ACCOUNTNBR>GGAHAHA</ACCOUNTNBR> <ID>29499785613092400202</ID> </Data></ExtendedData>'),
(2, 14, '<ExtendedData> <Data> <POLICYNBR>131313</POLICYNBR> <ACCOUNTNBR>GGAHAHA</ACCOUNTNBR> <ID>29499785613092400202</ID> </Data></ExtendedData>'),
(3, 14, '<ExtendedData> <Data> <POLICYNBR>54555</POLICYNBR> <ACCOUNTNBR>GGAHAHA</ACCOUNTNBR> <ID>123485613092400202</ID> </Data></ExtendedData>'),
(4, 13, '<ExtendedData> <Data> <POLICYNBR>54555</POLICYNBR> <ACCOUNTNBR>GGAHAHA</ACCOUNTNBR> <ID>123485613092400202</ID> </Data></ExtendedData>')
预期结果:- 如果我通过 Account id =14 那么我应该能够在响应中看到两条记录,因为对于 accountId=14 标签在 ExtendedData 列中具有相同的值。
这是我的脚本:-但它似乎不起作用,它没有给出我期望的结果。
select * from Table1 where AccountId =14 and
ExtendedData.value('(/ExtendedData/Data/ID/text())[1]','varchar(10)') = select CAST(ExtendedData as XML).value('(/ExtendedData/Data/ID/)[1]', 'nvarchar(20)') from Table1 where ExtendedData.value('(/ExtendedData/Data/ID/text())[1]','varchar(10)')
请给我建议
表名是Table1
,Id
列是主键。
【问题讨论】:
在提出问题时,您需要提供一个可重现的最小示例。请参考以下链接:***.com/help/minimal-reproducible-example 请提供以下内容: (1) DDL 和样本数据填充,即 CREATE table(s) 加上 INSERT T-SQL 语句。 (2) 你需要做什么,即逻辑和你的代码尝试在 T-SQL 中实现它。 (3) 期望的输出,基于上面#1 中的样本数据。 (4) 你的 SQL Server 版本 (SELECT @@version;) 根据建议,我添加了所有必需的详细信息。 Kumas、##1、3 和 4 不见了。 我已更新 - SQL Server 2012 ##1,3 怎么样? 【参考方案1】:听起来你只需要一个having
,在提取了相关的 id 值之后
select t.AccountId, v.ExtendedId
from Table1 t
cross apply (values(
ExtendedData.value('(/ExtendedData/Data/ID/text())[1]','varchar(10)')
) ) v(ExtendedId)
where AccountId = 14
group by t.AccountId, v.ExtendedId
having count(*) > 1
【讨论】:
【参考方案2】:首先是一些可重复使用的示例数据:
DECLARE @xml XML =
'<ExtendedData>
<Data>
<PolNbr>123999</PolNbr>
<ActNbr>ABCZZZ</ActNbr>
<ID>555444</ID>
</Data>
</ExtendedData>
<ExtendedData>
<Data>
<PolNbr>123999</PolNbr>
<ActNbr>ABCXXX</ActNbr>
<ID>555667</ID>
</Data>
</ExtendedData>
<ExtendedData>
<Data>
<PolNbr>123111</PolNbr>
<ActNbr>ABCZZZ</ActNbr>
<ID>555667</ID>
</Data>
</ExtendedData>
<ExtendedData>
<Data>
<PolNbr>123113</PolNbr>
<ActNbr>ABCXXX</ActNbr>
<ID>555666</ID>
</Data>
</ExtendedData>'
SELECT
ID = n.X.value('(ID)[1]','varchar(100)'),
PolNbr = n.X.value('(PolNbr)[1]','VARCHAR(100)'),
ActNbr = n.X.value('(ActNbr)[1]','varchar(100)')
FROM (VALUES(@xml)) AS f(X)
CROSS APPLY f.X.nodes('/ExtendedData/Data') AS n(X);
注意输出:
ID PolNbr ActNbr
-------- --------- ----------
555444 123999 ABCZZZ
555667 123999 ABCXXX
555667 123111 ABCZZZ
555666 123113 ABCXXX
现在我们可以调整查询以识别任何重复值:
--==== ID
SELECT ID_Duplicates = nd.X
FROM (VALUES(@xml)) AS f(X)
CROSS APPLY f.X.nodes('/ExtendedData/Data') AS n(X)
CROSS APPLY (VALUES(n.X.value('(ID)[1]','varchar(100)'))) AS nd(X)
GROUP BY nd.X
HAVING COUNT(*) > 1
--==== PolNbr
SELECT PolNbr_Duplicates = nd.X
FROM (VALUES(@xml)) AS f(X)
CROSS APPLY f.X.nodes('/ExtendedData/Data') AS n(X)
CROSS APPLY (VALUES(n.X.value('(PolNbr)[1]','varchar(100)'))) AS nd(X)
GROUP BY nd.X
HAVING COUNT(*) > 1;
--==== PolNbr
SELECT ActNbr_Duplicates = nd.X
FROM (VALUES(@xml)) AS f(X)
CROSS APPLY f.X.nodes('/ExtendedData/Data') AS n(X)
CROSS APPLY (VALUES(n.X.value('(ActNbr)[1]','varchar(100)'))) AS nd(X)
GROUP BY nd.X
HAVING COUNT(*) > 1;
结果:
ID_Duplicates
------------------------------------------
555667
PolNbr_Duplicates
------------------------------------------
123999
ActNbr_Duplicates
------------------------------------------
ABCXXX
ABCZZZ
【讨论】:
艾伦,看来 OP 想要完整地比较一列中的 XML,没有任何粉碎。 感谢艾伦的回复。在我的情况下,正如我在问题中提到的那样,我需要在给定 AccountId 的 ExtendedData 列内的以上是关于在 SQL Server XML 列中,如何验证相同的值是不是存在于多行中的主要内容,如果未能解决你的问题,请参考以下文章
动态获取 SQL Server 中不同列中的 XML 数据类型值
如何从 SQL Server 中的 XML 元素获取特定属性