Converter várias linhas em um com a vírgula como separador [duplicado]
Pergunta
Esta questão já tem uma resposta aqui:
Se eu questão SELECT username FROM Users
eu recebo este resultado:
username -------- Paul John Mary
mas o que eu realmente preciso é um linha com todos os valores separados por vírgula, assim:
Paul, John, Mary
Como posso fazer isso?
Solução
Isso deve funcionar para você. Testado todo o caminho de volta para SQL 2000.
create table #user (username varchar(25))
insert into #user (username) values ('Paul')
insert into #user (username) values ('John')
insert into #user (username) values ('Mary')
declare @tmp varchar(250)
SET @tmp = ''
select @tmp = @tmp + username + ', ' from #user
select SUBSTRING(@tmp, 0, LEN(@tmp))
Outras dicas
select
distinct
stuff((
select ',' + u.username
from users u
where u.username = username
order by u.username
for xml path('')
),1,1,'') as userlist
from users
group by username
tinha um erro de digitação antes, as obras acima
boa revisão de várias abordagens:
artigo cópia -
Coalesça não é a resposta para concatentation corda em T-SQL Eu tenho visto muitos posts ao longo dos anos sobre o uso da função COALESCE para obter concatenação trabalhando em T-SQL. Este é um dos exemplos aqui (emprestado de Readifarian Marc Ridey).
DECLARE @categories varchar(200)
SET @categories = NULL
SELECT @categories = COALESCE(@categories + ',','') + Name
FROM Production.ProductCategory
SELECT @categories
Esta consulta pode ser bastante eficaz, mas necessidades de cuidados a tomar, eo uso de COALESCE deve ser bem compreendida. COALESCE é a versão do ISNULL que pode demorar mais de dois parâmetros. Ele retorna a primeira coisa na lista de parâmetros que não é nulo. Então, realmente não tem nada a ver com concatenação, e o seguinte pedaço de código é exatamente o mesmo - sem usar COALESCE:
DECLARE @categories varchar(200)
SET @categories = ''
SELECT @categories = @categories + ',' + Name
FROM Production.ProductCategory
SELECT @categories
Mas a natureza não-ordenada de bancos de dados faz com que este não confiável. Toda a razão pela qual T-SQL não (ainda) têm uma função concatenar é que este é um suplemento para o qual a ordem dos elementos é importante. Usando este método variável de atribuição de concatenação, você pode realmente achar que a resposta que se retornou não tem todos os valores nele, especialmente se você quiser que os substrings colocados em uma ordem particular. Considere o seguinte, que na minha máquina apenas retorna 'Acessórios, quando eu queria que ele retorne', Bicicletas, Vestuário, Componentes, Acessórios:
DECLARE @categories varchar(200)
SET @categories = NULL
SELECT @categories = COALESCE(@categories + ',','') + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)
SELECT @categories
Muito melhor é usar um método que faz ordem levar em consideração, e que foi incluído no SQL2005 especificamente com a finalidade de concatenação - FOR XML PATH ( '')
SELECT ',' + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)
FOR XML PATH('')
No post que fiz recentemente comparando GROUP BY e DISTINCT ao usar subqueries, demonstrei o uso de para o caminho XML ( ''). Ter um olhar para isso e você vai ver como ele funciona em uma subconsulta. A função de 'coisas' só é lá para remover a vírgula líder.
USE tempdb;
GO
CREATE TABLE t1 (id INT, NAME VARCHAR(MAX));
INSERT t1 values (1,'Jamie');
INSERT t1 values (1,'Joe');
INSERT t1 values (1,'John');
INSERT t1 values (2,'Sai');
INSERT t1 values (2,'Sam');
GO
select
id,
stuff((
select ',' + t.[name]
from t1 t
where t.id = t1.id
order by t.[name]
for xml path('')
),1,1,'') as name_csv
from t1
group by id
;
FOR XML PATH é uma das únicas situações em que você pode usar ORDER BY em uma subconsulta. O outro é TOP. E quando você usar uma coluna sem nome e para o caminho XML ( ''), você vai ter uma concatenação em linha reta, sem tags XML. Isto significa que as cordas será HTML codificado, por isso, se você está concatenando cordas que podem ter o caractere <(etc), então talvez você deve corrigir isso até mais tarde, mas de qualquer maneira, isso ainda é a melhor maneira de concatenar cadeias no SQL Server 2005.
com base na resposta mwigdahls. Se você também precisa fazer agrupamento aqui é como obtê-lo para parecer
group, csv
'group1', 'paul, john'
'group2', 'mary'
--drop table #user
create table #user (groupName varchar(25), username varchar(25))
insert into #user (groupname, username) values ('apostles', 'Paul')
insert into #user (groupname, username) values ('apostles', 'John')
insert into #user (groupname, username) values ('family','Mary')
select
g1.groupname
, stuff((
select ', ' + g.username
from #user g
where g.groupName = g1.groupname
order by g.username
for xml path('')
),1,2,'') as name_csv
from #user g1
group by g1.groupname
DECLARE @EmployeeList varchar(100)
SELECT @EmployeeList = COALESCE(@EmployeeList + ', ', '') +
CAST(Emp_UniqueID AS varchar(5))
FROM SalesCallsEmployees
WHERE SalCal_UniqueID = 1
SELECT @EmployeeList
Fonte: http://www.sqlteam.com/article/using -coalesce-to-build-vírgula-delimitado por corda
Você pode usar essa consulta para fazer a tarefa acima:
DECLARE @test NVARCHAR(max)
SELECT @test = COALESCE(@test + ',', '') + field2 FROM #test
SELECT field2 = @test
Para mais detalhes e explicação passo a passo visite o seguinte link http://oops-solution.blogspot.com/2011/ 11 / sql-server-convertido-table-column-data.html
Em SQLite este é mais simples. Eu acho que existem implementações semelhantes para MySQL, MSSql e Orable
CREATE TABLE Beatles (id integer, name string );
INSERT INTO Beatles VALUES (1, "Paul");
INSERT INTO Beatles VALUES (2, "John");
INSERT INTO Beatles VALUES (3, "Ringo");
INSERT INTO Beatles VALUES (4, "George");
SELECT GROUP_CONCAT(name, ',') FROM Beatles;
Uma solução limpa e flexível no MS SQL Server 2005/2008 é para criar uma função CLR Agregate.
Você vai encontrar muito poucos artigos (com código) em google .
Parece que este artigo percorre todo o processo usando C #.
Você pode usar o material () para linhas converter como valores separados por vírgula
select
EmployeeID,
stuff((
SELECT ',' + FPProjectMaster.GroupName
FROM FPProjectInfo AS t INNER JOIN
FPProjectMaster ON t.ProjectID = FPProjectMaster.ProjectID
WHERE (t.EmployeeID = FPProjectInfo.EmployeeID)
And t.STatusID = 1
ORDER BY t.ProjectID
for xml path('')
),1,1,'') as name_csv
from FPProjectInfo
group by EmployeeID;
Graças @AlexKuznetsov para a referência para obter essa resposta.
Se você está executando isso através de PHP, o que sobre isso?
$hQuery = mysql_query("SELECT * FROM users");
while($hRow = mysql_fetch_array($hQuery)) {
$hOut .= $hRow['username'] . ", ";
}
$hOut = substr($hOut, 0, strlen($hOut) - 1);
echo $hOut;