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.