【问题标题】:Find the duplicates in the Xml column在 Xml 列中查找重复项
【发布时间】:2013-10-03 06:47:16
【问题描述】:

我有一个表格,其中包含以下示例列,其中的数据如下所示。每个帐号都有一个对应的createddtxmlpayload 列值。

在给定的 4 行中,我需要找到有效的重复项。每个有效的帐号有 2 个 xml 行(一个报表和一个 pdf xml 记录)。如果帐号有 2 条具有相同类型的 xml 根节点的记录,例如 pdf 记录 (2335577),则它应该是重复的。如何通过查询 xml 列来过滤精确的重复项。请帮忙。

Records:  
    AccountNo   **Xmlpayload**  
    2335566     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/><ns0:Statement>
    2335566     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt> 
    2335577     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt>       
    2335577     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt>      
    4332355     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt>       
    4332355     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/></ns0:Statement>      
    6723588     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/></ns0:Statement>       
    6723588     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/></ns0:Statement>   

My Expected Output:  
    2335577     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt>       
    2335577     <ns0:PDFStmt xmlns:ns0="uri"><empid>123<empid/></ns0:PDFStmt>      
    6723588     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/></ns0:Statement>       
    6723588     <ns0:Statement xmlns:ns0="uri"><empid>123<empid/></ns0:Statement>   

我使用的是 SQL 2008 R2 版本。

【问题讨论】:

  • SQL 只是 结构化查询语言 - 许多数据库系统使用的语言,但不是数据库产品...很多事情都是特定于供应商的 - 所以我们真的需要知道您正在使用什么数据库系统(以及哪个版本)(请相应地更新标签)......

标签: sql xml sql-server-2008 tsql sqlxml


【解决方案1】:

对于 SQL Server,您可以使用 sqlxml 中的 exist() 方法,如下所示:

with xmlnamespaces ('uri' as ns0)
select *
from Table1 as t
where t.Xmlpayload.exist('ns0:PDF[2]') = 1

或者您可以使用 xquery count() 函数和 value() 方法:

with xmlnamespaces ('uri' as ns0)
select *
from Table1 as t
where t.Xmlpayload.value('count(ns0:PDF)', 'int') > 1;

sql fiddle demo

更新

如果每个 AccountNo 都有一个,则可以使用此查询:

with xmlnamespaces ('uri' as ns0)
select *
from Table2 as t
where t.Xmlpayload.exist('ns0:PDFStmt[2]') = 1

如果每个 AccountNo 有几行(并且希望在结果集中获取 Xmlpayload):

with
xmlnamespaces ('uri' as ns0),
cte as (
    select
        *, count(*) over(partition by AccountNo) as cnt
    from Table1 as t
    where t.Xmlpayload.exist('ns0:PDFStmt') = 1
)
select *
from cte
where cnt > 1;

sql fiddle demo

【讨论】:

  • 嘿 Roman,我刚刚重组了我的记录,并为您提供了预期的输出。我运行了您的查询,但它没有为我获取任何结果集。我需要根据根节点名称过滤每个帐号的副本。请查看预期输出。
  • @user1762476 你有 4 行和 xml 有两个元素还是有 8 行?
  • 你的查询让我得到了重复。谢谢!!我使用以下查询解决了自己,我同时申请了 pdfstmt 和语句根节点。 WITH Xmlnamespaces ('uri' AS ns0) SELECT C1.query('fn:local-name(.)') AS Nodes, xmlPayload.value('(/ns0:PDFStmt/AccountNumber)[1]', 'nvarchar(max )') AS AccountNumber FROM #TempPR CROSS APPLY #TempPR.msgPayload.nodes('/ns0:PDFStmt') AS T1 (C1)
【解决方案2】:

我不是 100% 你想数的。我确定的是,您可以像这样在 MSSQL 版本中计算 XML 文件中的节点:

declare @xml xml
select @xml= convert(xml,N'<ns0 xmlns:ns0="uri"><empid>123</empid><age>23</age></ns0>
<ns0 xmlns:ns0="uri"><empid>123</empid><age>32</age></ns0>    
<ns0 xmlns:ns0="uri"><empid>123</empid><age>23</age></ns0>
<ns0 xmlns:ns0="uri"><empid>123</empid><age>32</age></ns0>')

select count(*) as nr
from @xml.nodes('root/ns0/empid') as S(N)

请注意,我还修改了您的 xml,因为它无效。我变了 empid>123 empid/> 在 empid>123 /empid>

,年龄相同

我删除了 :Statement 和 :PDF。这部分是有效的,但我不知道用于搜索这样的 throw 节点的 sysntax,但也适用于它们。

【讨论】:

  • 我没想到只是上面给出的计数。我需要通过过滤 xml 列根节点来查找 accountno 重复项的数量。正如我在问题中明确指出的那样,每个帐号都有两个 xmlpayload 行(一个以“statement”和“pdf”为根),这是一个有效记录。如果一个帐号有两行具有相同的根节点,则这些记录是重复的。
猜你喜欢
  • 2013-02-21
  • 1970-01-01
  • 2013-11-17
  • 2019-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-03
相关资源
最近更新 更多