考虑一个包含名称的数据库表,其中有三行:
Peter
Paul
Mary
有没有一种简单的方法可以把它变成彼得、保罗、玛丽的一串?
考虑一个包含名称的数据库表,其中有三行:
Peter
Paul
Mary
有没有一种简单的方法可以把它变成彼得、保罗、玛丽的一串?
当前回答
使用递归查询,您可以执行以下操作:
-- Create example table
CREATE TABLE tmptable (NAME VARCHAR(30)) ;
-- Insert example data
INSERT INTO tmptable VALUES('PETER');
INSERT INTO tmptable VALUES('PAUL');
INSERT INTO tmptable VALUES('MARY');
-- Recurse query
with tblwithrank as (
select * , row_number() over(order by name) rang , count(*) over() NbRow
from tmptable
),
tmpRecursive as (
select *, cast(name as varchar(2000)) as AllName from tblwithrank where rang=1
union all
select f0.*, cast(f0.name + ',' + f1.AllName as varchar(2000)) as AllName
from tblwithrank f0 inner join tmpRecursive f1 on f0.rang=f1.rang +1
)
select AllName from tmpRecursive
where rang=NbRow
其他回答
一个现成的解决方案,没有额外的逗号:
select substring(
(select ', '+Name AS 'data()' from Names for xml path(''))
,3, 255) as "MyList"
空列表将导致NULL值。通常,您会将列表插入到表列或程序变量中:根据需要调整最大长度255。
(迪瓦卡尔和延斯·弗兰森提供了很好的答案,但需要改进。)
SQL Server 2017+和SQL Azure:STRING_AGG
从SQL Server的下一个版本开始,我们终于可以跨行连接,而无需使用任何变量或XML开关。
STRING_AGG(Transact-SQL)
不分组
SELECT STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department;
分组时:
SELECT GroupName, STRING_AGG(Name, ', ') AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
带分组和子排序
SELECT GroupName, STRING_AGG(Name, ', ') WITHIN GROUP (ORDER BY Name ASC) AS Departments
FROM HumanResources.Department
GROUP BY GroupName;
在PostgreSQL中-array_agg
SELECT array_to_string(array_agg(DISTINCT rolname), ',') FROM pg_catalog.pg_roles;
或STRING_AGG
SELECT STRING_AGG(rolname::text,',') FROM pg_catalog.pg_roles;
使用此项:
ISNULL(SUBSTRING(REPLACE((select ',' FName as 'data()' from NameList for xml path('')), ' ,',', '), 2, 300), '') 'MyList'
其中“300”可以是任何宽度,考虑到您认为将显示的最大项目数。
我真的很喜欢Dana回答的优雅,只想让它变得完整。
DECLARE @names VARCHAR(MAX)
SET @names = ''
SELECT @names = @names + ', ' + Name FROM Names
-- Deleting last two symbols (', ')
SET @sSql = LEFT(@sSql, LEN(@sSql) - 1)