【问题标题】:How to concatenate results in T-SQL into column?如何将 T-SQL 中的结果连接到列中?
【发布时间】:2011-11-09 05:23:50
【问题描述】:

我正在处理一个应该给我结果的查询:

|--姓名--|--姓--|--语言--|--日期-- | |詹姆斯 |赫特菲尔德 |英、英、法 | 2011-01-01| |拉斯 |乌尔里希 |英、法、加 | 2011-01-01|

但我的选择会得到一组行,例如:

|詹姆斯 |赫特菲尔德 | zh | 2011-01-01| |詹姆斯 |赫特菲尔德 |国标| 2011-01-01| |詹姆斯 |赫特菲尔德 |法语 | 2011-01-01| |拉斯 |乌尔里希 |国标| 2011-01-01| |拉斯 |乌尔里希 |法语 | 2011-01-01| |拉斯 |乌尔里希 |加州 | 2011-01-01|

您推荐哪种最佳方法“即时”将结果集转换为分组列中的逗号分隔值?我发现 CROSS APPLY 可以完成这项工作,但人们说这种方法非常消耗。此外,数据库拥有大量数据。

提前致谢, 问候, 阿德里安

【问题讨论】:

  • CROSS APPLY 是否需要太长时间 - 您需要多长时间才能加快速度?
  • 如果每个组中的排序不重要,那么 CLR 聚合可能是最快的。如果您需要特定的订单,FOR XML 是唯一可靠的方式(只要您的数据不包含某些有问题的字符)。
  • CROSS APPLY 让我很困惑。我需要将查询速度提高 >60%
  • 如果使用正确,CROSS APPLY 不会消耗。你能显示示例代码吗?此外,什么版本的 SQL Server,如这里给出的答案,将在 SQL Server 2005 和 2008 中工作,但不能在 SQL Server 2000 中工作。最后,你为什么要这样做?如果稍后在 SQL 中使用这些数据,这似乎是一个糟糕的计划,如果是为了显示,在 GUI/客户端应用程序中执行?
  • Metallica 参考文献加一

标签: sql tsql stored-procedures dynamic concatenation


【解决方案1】:

这里是最好的连接方法,它不会像其他 XML 方法那样扩展特殊字符:

--Concatenation with FOR XML & eliminating control/encoded char expansion "& < >"
set nocount on;
declare @YourTable table (RowID int, HeaderValue int, ChildValue varchar(5))
insert into @YourTable VALUES (1,1,'CCC')
insert into @YourTable VALUES (2,2,'B<&>B')
insert into @YourTable VALUES (3,2,'AAA')
insert into @YourTable VALUES (4,3,'<br>')
insert into @YourTable VALUES (5,3,'A & Z')
set nocount off
SELECT
    t1.HeaderValue
        ,STUFF(
                   (SELECT
                        ', ' + t2.ChildValue
                        FROM @YourTable t2
                        WHERE t1.HeaderValue=t2.HeaderValue
                        ORDER BY t2.ChildValue
                        FOR XML PATH(''), TYPE
                   ).value('.','varchar(max)')
                   ,1,2, ''
              ) AS ChildValues
    FROM @YourTable t1
    GROUP BY t1.HeaderValue

输出:

HeaderValue ChildValues
----------- ---------------
1           CCC
2           AAA, B<&>B
3           <br>, A & Z

(3 row(s) affected)

【讨论】:

  • 这仍然会影响某些角色。例如CHAR(11)CHAR(27)
  • @Martain,好点,但这些并不常见,而且从来没有出现在我在任何数据库中看到的任何用户输入或数据中。
  • 同意 - 实际上这不太可能出现。
  • 很好的答案,谢谢。我已经在 stackoverflow.com/a/5031297/303101 为你的其他生活 +1 了
【解决方案2】:

如果您的 SQL 版本支持 FOR XML 使用

select n.[name],CONVERT(VARCHAR(MAX),(SELECT *
        FROM (
                SELECT  l.[lang] + ' , '  AS '*'
                FROM    tblLang l
                WHERE l.[name]=n.[name]
                ) x
        FOR XML PATH (''), TYPE
    )) AS [Language]

from tblName n 

这假设像这样的简单表格

tblName
-------
name VARCHAR

tblLang
-------
lang VARCHAR
name VARCHAR

它还添加了一个尾随, :(

【讨论】:

  • 在包含&amp;gt;&amp;lt;&amp;amp; 或任何其他“特殊”字符的数据上尝试此方法,您会看到它将它们扩展为&amp;gt;&amp;lt;、和&amp;amp;,这可能不是预期的或想要的。请参阅我的回答,了解如何使用.value 消除这种情况
  • @KM 很有趣。老实说,我发现 FOR XML 相当莫名其妙!但我之前曾与它搏斗,给我想要的答案,这是我的帖子所依据的......
  • 直到 tsql 有一个合适的 CONCAT() aggergate 函数,你无能为力。
猜你喜欢
  • 2014-10-17
  • 1970-01-01
  • 2020-06-19
  • 2022-01-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-23
  • 1970-01-01
相关资源
最近更新 更多