将多行转换为逗号分隔符

如果我发出SELECT username FROM Users我得到这个结果:

用户名
 --------
保罗
约翰
玛丽

但我真正需要的是以逗号分隔的所有值的一行,如下所示:

保罗,约翰,玛丽

我该怎么做呢?

这应该适合你。 一直testing回到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)) 
  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 

之前有一个错字,上面的作品

好几个方法的回顾:

http://blogs.msmvps.com/robfarley/2007/04/07/coalesce-is-not-the-answer-to-string-concatentation-in-t-sql/

文章复制 –

合并不是在T-SQL中string连接的答案我已经看到多年来关于使用COALESCE函数获取在T-SQL中工作的string连接的许多post。 这是这里的一个例子(从Readifarian Marc Ridey借来的)。

 DECLARE @categories varchar(200) SET @categories = NULL SELECT @categories = COALESCE(@categories + ',','') + Name FROM Production.ProductCategory SELECT @categories 

这个查询可能是相当有效的,但是需要注意,并且应该正确理解使用COALESCE。 COALESCE是可以采用两个以上参数的ISNULL版本。 它返回参数列表中的第一个不为null的东西。 所以真的和串联无关,下面这段代码是完全一样的 – 没有使用COALESCE:

 DECLARE @categories varchar(200) SET @categories = '' SELECT @categories = @categories + ',' + Name FROM Production.ProductCategory SELECT @categories 

但是数据库的无序性使得这个不可靠。 T-SQL还没有一个连接函数的原因在于,这是一个集合,元素的顺序是重要的。 使用这种string连接的variables赋值方法,您可能会发现返回的答案并不包含所有的值,特别是如果您希望将子string按特定顺序放置。 考虑以下内容,在我的机器上只返回',配件',当我想要它返回',自行车,服装,部件,配件':

 DECLARE @categories varchar(200) SET @categories = NULL SELECT @categories = COALESCE(@categories + ',','') + Name FROM Production.ProductCategory ORDER BY LEN(Name) SELECT @categories 

更好的办法是使用一个不考虑顺序的方法,它专门用于string连接 – FOR XML PATH('')

 SELECT ',' + Name FROM Production.ProductCategory ORDER BY LEN(Name) FOR XML PATH('') 

在我最近使用子查询时比较了GROUP BY和DISTINCT后,我演示了使用FOR XML PATH('')。 看看这个,你会看到它是如何工作的子查询。 “STUFF”function仅用于删除前导逗号。

 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是可以在子查询中使用ORDER BY的唯一情况之一。 另一个是TOP。 而当你使用一个未命名的列和FOR XML PATH('')时,你会得到一个直接的连接,没有XML标签。 这确实意味着这些string是HTML编码的,所以如果你连接了可能带有<字符(等)的string,那么你应该在之后修正它,但是不pipe怎样,这仍然是连接string的最好方法在SQL Server 2005中。

 DECLARE @EmployeeList varchar(100) SELECT @EmployeeList = COALESCE(@EmployeeList + ', ', '') + CAST(Emp_UniqueID AS varchar(5)) FROM SalesCallsEmployees WHERE SalCal_UniqueID = 1 SELECT @EmployeeList 

来源: http : //www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string

您可以使用此查询来执行上述任务:

 DECLARE @test NVARCHAR(max) SELECT @test = COALESCE(@test + ',', '') + field2 FROM #test SELECT field2 = @test 

有关详细信息和分步说明,请访问以下链接http://oops-solution.blogspot.com/2011/11/sql-server-convert-table-column-data.html

build立在mwigdahls的答案。 如果你还需要在这里做分组是如何让它看起来像

 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 

MS SQL Server 2005/2008中一个干净灵活的解决scheme是创build一个CLR Agregate函数。

你会在google上find不less文章(有代码)。

它看起来像这篇文章引导您使用C#的整个过程。

在SQLite中,这更简单。 我认为有类似的实现MySQL,MSSql和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; 

您可以使用stuff()将行转换为逗号分隔值

 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; 

感谢@AlexKuznetsov为参考得到这个答案。

如果你通过PHP执行这个,那么这个怎么样?

 $hQuery = mysql_query("SELECT * FROM users"); while($hRow = mysql_fetch_array($hQuery)) { $hOut .= $hRow['username'] . ", "; } $hOut = substr($hOut, 0, strlen($hOut) - 1); echo $hOut;