Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Comment utiliser XQuery pour simuler STRING_AGG() (concaténation de chaînes groupées) ?

Cherchez-vous cela ?

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);

Le résultat

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

UPDATE Adresses multiples et données identiques

Vous pouvez essayer ceci (selon votre commentaire)

Vos données de test avec une deuxième adresse et une adresse copiée :

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>'

--La ​​requête

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);

L'idée en bref :

Nous utilisons le premier XQuery pour créer un fragment XML simple comme celui-ci

<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>

Avec cela, nous pouvons utiliser un deuxième XQuery et placer distinct-values() là.