Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

Selecione de volta uma lista delimitada por vírgulas agrupada por um ID

select ET1.EntryID,
       (
       select ', '+T.Name
       from Tags as T
         inner join EntryTag as ET2
           on T.TagID = ET2.TagID
       where ET1.EntryID = ET2.EntryID
       for xml path(''), type
       ).value('substring(text()[1], 3)', 'varchar(max)') as TagsCommaDelimited
from EntryTag as ET1
group by ET1.EntryID

Dissecando a consulta

A consulta principal faz um group by para que você obtenha apenas uma linha para cada EntryID .

A coluna TagsCommaDelimited é criado com uma subconsulta correlacionada.

No SQL Server for xml path é usado para criar uma representação XML de um resultado de consulta. Você tem um bom controle sobre como o XML é criado usando aliases de coluna e os parâmetros para path e root .

O valor concatenado ', '+T.Name na subconsulta correlacionada não terá um nome de coluna e o parâmetro vazio para for xml path('') cria o xml sem nenhuma tag. Haverá apenas um valor de texto retornado.

Quando você adiciona type para um for xml consulta o tipo de dados será XML .

Para obter um valor de um XML, você deve usar o value() método. Você pode converter para uma string, mas se fizer isso, obterá, por exemplo, & na string onde quer que você tenha usado & .

O primeiro parâmetro no value() function é a expressão xQuery usada para obter o valor desejado. Use text() para especificar que você deseja apenas o valor para o elemento atual. [1] está dizendo ao SQL Server que você deseja que o primeiro nó de texto seja encontrado (você só tem um aqui), mas ainda é necessário.

A string criada pelo for xml query tem uma vírgula extra e um espaço no início da string e isso precisa ser removido. Aqui eu uso a função XQuery substring para obter tudo, exceto os dois primeiros caracteres.

O segundo parâmetro para value() especifica o tipo de dados que deve ser retornado.