【问题标题】:Concatenating Column Values into a Comma-Separated List将列值连接到逗号分隔的列表中
【发布时间】:2010-11-06 02:24:34
【问题描述】:

什么是 TSQL 语法来格式化我的输出,以便列值显示为字符串,用逗号分隔。

例如,我的表 CARS 有以下内容:

CarID    CarName  
----------------
    1    Porsche  
    2    Mercedes  
    3    Ferrari  

如何获得车名:Porsche, Mercedes, Ferrari

【问题讨论】:

  • group_concat(field_here, ',') 如果您使用的是 MySQL。 array_to_string(array_accum(field_here), ',') 如果您使用的是 PostgreSQL。但由于您使用的是 MSSQL,因此只需创建一个返回逗号分隔字符串的函数。使用 ConcernedOfTunbridgeW 代码 sn-p,放入一个函数
  • @van:在我看来,提出问题的方式至少让他努力做到尽可能清晰并保持可读性,因此,我认为他也费尽心思尝试自己找答案。
  • @van 这很有趣,我以为你的评论是最近的,然后我注意到它已经超过 5 年了;这个问题is still asked at least once a week.

标签: sql-server tsql


【解决方案1】:

例如,您可以使用coalesce 执行快捷方式来连接表中记录中的一系列字符串。

declare @aa varchar (200)
set @aa = ''

select @aa = 
    case when @aa = ''
    then CarName
    else @aa + coalesce(',' + CarName, '')
    end
  from Cars

print @aa

【讨论】:

  • 为什么将 @aa 初始化为 '' 而不是在第一个 when 中检查 is null?还有,为什么要合并?最后,您不想用isnull(CarName, '') 包裹CarName 以确保安全吗?
  • 你的coalesce放错地方了;它应该像 @aa + coalesce(',' + CarName, '') 一样包装 CarName (检查建议的编辑),以在 CarName 为空的情况下将其转换为空白字符串。正如你所拥有的,每次 CarName 为 NULL 时,@aa 都会被清空。
  • @ConcernedOfTunbridgeWells - 这种方法可以用于执行动态 SQL 语句,例如:SELECT col1 as 'col1 name', coln as 'coln name' FROM <table> 吗?
  • @NickBraunagel 是的,你可以这样做,我以前做过。
  • 谢谢,我最终在显示名称周围添加了括号 ([) 来实现这一点。
【解决方案2】:
DECLARE @CarList nvarchar(max);
SET @CarList = N'';
SELECT @CarList+=CarName+N','
FROM dbo.CARS;
SELECT LEFT(@CarList,LEN(@CarList)-1);

感谢 SO 上的任何人向我展示了在查询期间使用累积数据。

【讨论】:

  • 如果“CarName”是一个int(即“CarId),请执行SELECT @CarList+=CONVERT(varchar(20),CarId,0)+N','
【解决方案3】:
SELECT LEFT(Car, LEN(Car) - 1)
FROM (
    SELECT Car + ', '
    FROM Cars
    FOR XML PATH ('')
  ) c (Car)

【讨论】:

  • 谢谢。我从未见过这种命名子查询列的语法。我想知道您是否可以编辑您的答案以包含允许这样做的 TSQL 语法部分?
  • 这是我在 Stackoverflow 上学到的。我不知道在任何 TSQL 规范中是否提到了它。
  • 我想知道这个比 Vaibhav 下面的“STUFF”答案快还是慢...两者都很棒而且 sn-p-y(可重复使用)
  • 我怀疑任何性能差异是显而易见的,因为这两种解决方案的工作压力是相同的。但与往常一样,请在不同的场景中尝试这两种方法,如果您想确定,请进行测量。
【解决方案4】:

查询中的另一种解决方案:

select 
    Id, 
    STUFF(
        (select (', "' + od.ProductName + '"')
        from OrderDetails od (nolock)
        where od.Order_Id = o.Id
        order by od.ProductName
        FOR XML PATH('')), 1, 2, ''
    ) ProductNames
from Orders o (nolock)
where o.Customer_Id = 525188
order by o.Id desc

(编辑:感谢@user007 的 STUFF 声明)

【讨论】:

  • Netezza 中是否有解决方案
  • 添加 where 和 order 子句的好方法
【解决方案5】:

你可以使用一些东西来做到这一点:

SELECT Stuff(
    (
    SELECT ', ' + CARS.CarName
    FROM CARS
    FOR XML PATH('')
    ), 1, 2, '') AS CarNames

【讨论】:

  • 基本上只是这里答案的简化版本——stackoverflow.com/questions/6899/…——但我发现这个更简单,因为你可以将它插入到像 SSMSBoost 或 Redgate SQLPrompt 这样的“sn-p 管理器”中并将其保存在您自己的个人工具箱中。
【解决方案6】:
 DECLARE @SQL AS VARCHAR(8000)
SELECT @SQL = ISNULL(@SQL+',','') + ColumnName FROM TableName
SELECT @SQL

【讨论】:

  • @PhilS,不,它会给出正确的答案,如果你在员工表上运行上述查询的名字,示例结果将是 Jhon,Thomas,PhilS
  • @john:哦,你确实是对的。对不起,我的错。我会推翻反对票,但除非编辑答案,否则系统不会让我...
【解决方案7】:

如果您在 SQL Server 2017 或 Azure SQL 数据库上运行,您可以执行以下操作:

 SELECT STRING_AGG(CarName,',') as CarNames
 FROM CARS 

【讨论】:

  • 是时候创建这个函数了!
  • LISTAGG() 的等价物是很久以前的事了,绝对应该在 SQL Server 2017 中使用。
  • 这应该被赞成!
【解决方案8】:

请用下面的代码试试这个:

DECLARE @listStr VARCHAR(MAX)
SELECT @listStr = COALESCE(@listStr+',' , '') + CarName
FROM Cars
SELECT @listStr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-23
    • 2020-09-14
    • 1970-01-01
    相关资源
    最近更新 更多