Tecnologia

Como retornar mais de um valor separados por vírgula em um subselect

Quando tentamos executar um subselect que retorna mais de um resultado recebemos a seguinte mensagem:

'Msg 512, Level 16, State 1, Line 1
2 Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, < ,>, >= or when the subquery is used as an expression.'

No entanto podemos nos deparar em algumas situações em nosso dia-dia em que seja necessário retornar mais de um valor em um subselect em uma consulta, por exemplo, as funções de um determinado funcionário. Para exemplificar essa situação vamos criar duas tabelas temporárias e poupá-las.


create table #temp_funcionarios
(
funcionariosId int,
funcionariosNome varchar(15)
)
create table #temp_funcoes
(
funcoesId int,
funcionariosId int,
funcionariosDesc varchar(15)
)
−−inserindo valores à  tabela de funcionarios
insert into #temp_funcionarios values (1,'Gustavo')
−−inserindo valores à  tabela de funcoes do funcionario
insert into #temp_funcoes values (1,1,'Analisar')
−−inserindo valores à  tabela de funcoes do funcionario
insert into #temp_funcoes values (2,1,'Programar')
Nesse momento já temos as tabelas temporárias (#temp_funcionarios) e (#temp_funcoes).
select * from #temp_funcionarios
inner join #temp_funcoes on #temp_funcionarios.funcionariosId = #temp_funcoes.funcionariosId

image

Nesse momento, nosso objetivo é buscar os funcionários e todas as suas funções separadas por vírgula.


select funcionariosId, funcionariosNome,
SUBSTRING( (SELECT ',', funcionariosDesc AS [data()]
FROM #temp_funcoes WHERE  #temp_funcionarios.funcionariosId = #temp_funcoes.funcionariosId
FOR XML PATH('')   ) , 2, 9000) as funcDescricoes
from #temp_funcionarios

image

A consulta sql acima atinge esse objetivo utilizando a função (FOR XML PATH), essa função retorna um XML, e a função (SUBSTRING) é responsável por remover a virgula inicial do resultado. Você também pode utilizar o (FOR XML PATH) para retornar um xml separado por tags, basta incluir tag dentro da função, exemplo: (FOR XML PATH(‘nome_tag’))

Outra forma de retornar os valores de um select separados por vírgula, porém sem subselect e utilizando TSQL é essa:

declare @resultado varchar(200);
declare @virgula varchar(1);
set @resultado = '';
set @virgula = '';
select @resultado = @resultado + @virgula + funcionariosDesc, @virgula = ',' from #temp_funcoes
select @resultado

Caso você deseja apagar as tabelas temporárias, basta executar os comandos abaixo:

delete from #temp_funcionarios
delete from #temp_funcoes

Agradeço a atenção de todos, espero que o post seja útil. Qualquer dúvida ou sugestão deixe seu comentário abaixo.

Gustavo Resende

Comentários

Deixe uma resposta