【问题标题】:How to use XQuery to simulate STRING_AGG() (grouped string concatenation)?如何使用 XQuery 模拟 STRING_AGG()(分组字符串连接)?
【发布时间】:2020-03-20 20:43:27
【问题描述】:

我有需要转换为关系形式的 XML 数据。我使用 XQuery 因为我不知道地址节点的数量。我想用逗号分隔整个地址/地址。我想我需要使用 LET 子句,但我仍然收到错误。

这是我的代码:

declare @xml as xml = '<root>
    <Row>
        <proceeding>
            <signatures>V GU 86/18</signatures>
            <signatures>V GUp 9/19</signatures>
            <signatures>V GUp 8/19</signatures>
        </proceeding>
        <entity>
            <info>
                <cleaned_name>Kate Smith</cleaned_name>
            </info>
            <address>
                <town>London </town>
                <house_number>1 </house_number>
                <flat_number>1</flat_number>
                <street>Downing Street</street>
                <zip_code>00-001</zip_code>
            </address>
        </entity>
        <entity>
            <info>
                <cleaned_name>John Smith</cleaned_name>
            </info>
            <address>
                <town>Washington </town>
                <house_number>1</house_number>
                <flat_number>1</flat_number>
                <street>Pennsylvania Avenue</street>
                <zip_code>00-001</zip_code>
            </address>
        </entity>
    </Row>
</root>'
select 
    isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
   ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
   --,isnull(STUFF(a.x.query('for $s in entity let $L := $s/entity/address   return <x>{concat(",",Address="{$s/Address}")}</x>').value('.','varchar(max)'),1,1,''),'') 
from @xml.nodes('/root/Row') as a(x)

我想要的结果

【问题讨论】:

    标签: sql-server xml tsql sql-server-2012 xquery


    【解决方案1】:

    你在找这个吗?

    select 
     isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
    ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
    ,isnull(STUFF(a.x.query('for $s in entity
                             return <x>
                                    {
                                    concat(", ",($s/address/zip_code/text())[1]," "
                                               ,($s/address/town/text())[1]," "
                                               ,($s/address/street/text())[1]," "
                                               ,($s/address/house_number/text())[1],"/"
                                               ,($s/address/flat_number/text())[1]
                                              )
                                    }
                                    </x>').value('.','varchar(max)'),1,2,''),'') 
        from @xml.nodes('/root/Row') as a(x);
    

    结果

    Nazwa podmiotu          Sygnatura                           AllAdresses
    Kate Smith,John Smith   V GU 86/18,V GUp 9/19,V GUp 8/19    00-001 London  Downing Street 1 /1, 00-001 Washington  Pennsylvania Avenue 1/1
    

    更新多个地址和相同的数据

    你可以试试这个(根据你的评论)

    你的测试数据有一个第二个地址和一个复制地址:

    declare @xml as xml = '<root>
        <Row>
            <proceeding>
                <signatures>V GU 86/18</signatures>
                <signatures>V GUp 9/19</signatures>
                <signatures>V GUp 8/19</signatures>
            </proceeding>
            <entity>
                <info>
                    <cleaned_name>Kate Smith</cleaned_name>
                </info>
                <address>
                    <town>London </town>
                    <house_number>1 </house_number>
                    <flat_number>1</flat_number>
                    <street>Downing Street</street>
                    <zip_code>00-001</zip_code>
                </address>
                <address>
                    <town>Yorkshire </town>
                    <house_number>1 </house_number>
                    <flat_number>1</flat_number>
                    <street>Morning Street</street>
                    <zip_code>00-999</zip_code>
                </address>
            </entity>
            <entity>
                <info>
                    <cleaned_name>John Smith</cleaned_name>
                </info>
                <address>
                    <town>Washington </town>
                    <house_number>1</house_number>
                    <flat_number>1</flat_number>
                    <street>Pennsylvania Avenue</street>
                    <zip_code>00-001</zip_code>
                </address>
                <address>
                    <town>Washington </town>
                    <house_number>1</house_number>
                    <flat_number>1</flat_number>
                    <street>Pennsylvania Avenue</street>
                    <zip_code>00-001</zip_code>
                </address>
            </entity>
        </Row>
    </root>'
    

    --查询

    select 
     isnull(STUFF(a.x.query('for $s in  entity/info/cleaned_name return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Nazwa podmiotu' 
    ,isnull(STUFF(a.x.query('for $s in proceeding/signatures return <x>{concat(",",$s)}</x>').value('.','varchar(max)'),1,1,''),'') as 'Sygnatura'
    ,isnull(STUFF(a.x.query('for $s in entity/address
                                return
                                <x>{concat(", ",($s/zip_code/text())[1]," "
                                               ,($s/town/text())[1]," "
                                               ,($s/street/text())[1]," "
                                               ,($s/house_number/text())[1],"/"
                                               ,($s/flat_number/text())[1]
                                           )}</x>')
                       .query('for $a in distinct-values(/x/text()) return $a').value('.','varchar(max)'),1,2,''),'') 
        from @xml.nodes('/root/Row') as a(x);
    

    简而言之:

    我们使用第一个 XQuery 创建一个像这样的简单 XML 片段

    <x>, 00-001 London  Downing Street 1 /1</x>
    <x>, 00-999 Yorkshire  Morning Street 1 /1</x>
    <x>, 00-001 Washington  Pennsylvania Avenue 1/1</x>
    <x>, 00-001 Washington  Pennsylvania Avenue 1/1</x>
    

    有了这个,我们可以使用第二个 XQuery 并将distinct-values() 放在那里。

    【讨论】:

    • 好答案,我这边+1。
    • @Shnugo 这正是我想要完成的。你一如既往的可靠。非常感谢。
    • @Shnugo,我只是想知道我是否可以在这个合成器中使用不同的值?当我以这种方式使用它时: distinct-values (entity) 我得到一个错误。
    • @Arkadiusz 每个实体可以有多个地址吗?您是否期望相同的地址(在所有字段中)?
    • @Shnugo,每个实体可以有多个地址,并且它们在所有字段中都可以相同。
    猜你喜欢
    • 1970-01-01
    • 2021-06-26
    • 1970-01-01
    • 2017-04-27
    • 1970-01-01
    • 2020-07-27
    • 2011-08-08
    • 2010-10-09
    • 1970-01-01
    相关资源
    最近更新 更多