SELECT username FROM Users
,我会得到如下结果:
username -------- Paul John Mary但是我真正需要的是一行,将所有值用逗号分隔开,就像这样:
Paul, John, Mary如何实现呢?
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
之前有个错别字,上面的代码可以正常工作
这应该适用于您。已经测试过了,可以追溯到 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 SUBSTRING(@tmp, 0, LEN(@tmp))
看起来不正确(对我来说),但显然是可以运行的(我试过了)。MSDN页面中关于substring
的晦涩难懂的语言未能说明为什么它会工作,但我猜想它的结束点是start_expression + length_expression
而没有更正start_expression
,所以如果你用一个小于1
的数字开始,它将从“第一个字符”(例如1
)开始,我想它算是通过后门实现了。虽然如此,我还是打算使用select SUBSTRING(@tmp, 1, LEN(@tmp) - 1)
。 - T.J. Crowderselect SUBSTRING('testing', -2, 5)
会给出我们'te'
(例如,正是select SUBSTRING('testing', 1, 2)
所给出的),因为在两种情况下得到的(独占式)结束索引都是3
。这不是我想要依赖的行为。你有什么具体原因吗? - T.J. Crowderstuff(str,len(str)-1,1,'')
更快。 - Hogan多种方法的良好评论:
文章副本 -
在T-SQL中,Coalesce不是字符串连接的答案。多年来,我看到了许多关于使用COALESCE函数在T-SQL中实现字符串连接的帖子。这是其中一个例子(借鉴自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目前没有串联函数的主要原因是这是一个需要考虑元素顺序的聚合操作。使用变量赋值的字符串拼接方法时,你可能会发现返回的结果并不包含所有的值,特别是当你希望将子字符串按照特定顺序排列时。考虑以下示例,在我的机器上只返回了',Accessories',但我希望它返回',Bikes,Clothing,Components,Accessories':
DECLARE @categories varchar(200)
SET @categories = NULL
SELECT @categories = COALESCE(@categories + ',','') + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)
SELECT @categories
SELECT ',' + Name
FROM Production.ProductCategory
ORDER BY LEN(Name)
FOR XML PATH('')
最近我发布了一篇关于在使用子查询时比较GROUP BY和DISTINCT的文章,在里面展示了使用FOR XML PATH('')的方法。看一下这篇文章,你就会知道它在子查询中是如何工作的。'STUFF'函数只是为了去掉前导逗号。
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标记。这意味着字符串将被HTML编码,因此,如果您正在连接可能包含<字符(等)的字符串,则您应该在此之后进行修复,但无论如何,这仍然是SQL Server 2005中连接字符串的最佳方法。
在 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
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
该链接介绍了如何将SQL Server表列数据转换为XML格式,并提供了详细的步骤说明。DECLARE @EmployeeList varchar(100)
SELECT @EmployeeList = COALESCE(@EmployeeList + ', ', '') +
CAST(Emp_UniqueID AS varchar(5))
FROM SalesCallsEmployees
WHERE SalCal_UniqueID = 1
SELECT @EmployeeList
source: http://www.sqlteam.com/article/using-coalesce-to-build-comma-delimited-string
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;
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;
tsql
,即 MS SQL Server。在 SQL Server 中不存在 GROUP_CONCAT
。然而,自 SQL Server 2017 起,有一个名为 STRING_AGG
的函数,它具有类似的功能。 - Simon Elms$hQuery = mysql_query("SELECT * FROM users");
while($hRow = mysql_fetch_array($hQuery)) {
$hOut .= $hRow['username'] . ", ";
}
$hOut = substr($hOut, 0, strlen($hOut) - 1);
echo $hOut;
<
或&
的数据。 - keeehlanFOR XML
会自动编码,请查看 http://sqlfiddle.com/#!6/b824a/1。 - Hogan