【问题标题】:Concatenate values based on ID根据 ID 连接值
【发布时间】:2011-09-30 00:08:55
【问题描述】:

我有一个名为 Results 的表,数据如下所示:

Response_ID    Label
12147          It was not clear
12458          Did not Undersstand
12458          Was not resolved
12458          Did not communicate
12586          Spoke too fast
12587          Too slow

现在我希望输出显示每个 ID 一行,并将 Label 中的值连接起来并用逗号分隔

我的输出应该是这样的:

Response_ID    Label
12147          It was not clear
12458          Did not Undersstand,Was not resolved,Did not communicate
12586          Spoke too fast
12587          Too Slow

我该怎么做:

【问题讨论】:

    标签: sql sql-server sql-server-2005 tsql sql-server-2008


    【解决方案1】:

    查看下面的链接,它通过许多不同的解决方案来解决您的问题

    http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

    【讨论】:

      【解决方案2】:
      DECLARE @Results TABLE(Response_ID INT, Label VARCHAR(80));
      
      INSERT @Results(Response_ID, Label)
      SELECT 12147,'It was not clear'
      UNION SELECT 12458,'Did not Undersstand'
      UNION SELECT 12458,'Was not resolved'
      UNION SELECT 12458,'Did not communicate'
      UNION SELECT 12586,'Spoke too fast'
      UNION SELECT 12587,'Too slow';
      
      WITH x AS 
      (
        SELECT Response_ID FROM @Results 
        GROUP BY Response_ID
      )
      SELECT x.Response_ID, Label = STUFF((SELECT ',' + Label
          FROM @Results WHERE Response_ID = x.Response_ID
          FOR XML PATH('')), 1, 1, '')
          FROM x;
      

      【讨论】:

        【解决方案3】:

        如果没有子查询中的 order by 语句,您无法确定连接的字符串的顺序。 .value('.', 'varchar(max)') 部分用于处理 Label 包含 XML-unfriendly 字符(如 &)的情况。

        declare @T table(Response_ID int, Label varchar(50))
        insert into @T values
        (12147,          'It was not clear'),
        (12458,          'Did not Undersstand'),
        (12458,          'Was not resolved'),
        (12458,          'Did not communicate'),
        (12586,          'Spoke too fast'),
        (12587,          'Too slow')
        
        select T1.Response_ID,
               stuff((select ','+T2.Label
                      from @T as T2
                      where T1.Response_ID = T2.Response_ID
                      for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '') as Label
        from @T as T1
        group by T1.Response_ID
        

        【讨论】:

        • 关于 .value 的好点,我总是假设问题中的数据具有广泛的代表性。它不会导致错误,当然,只是显示实体(例如 &)。但是,我不太确定订单对 OP 是否重要 - 如果是,您会添加什么订单?我们需要更多信息。
        • @Aaron – 是的,我们需要有关订单的更多信息。我只是向@Sam 指出,即使此示例代码以预期的顺序连接字符串,也不能保证每次都会这样做。
        • 这不是一个好的解决方案,因为当表中有很多行时它是一个性能问题。 XML 函数很慢。
        【解决方案4】:

        考虑到这一点,它的性能非常好:

        http://jerrytech.blogspot.com/2010/04/tsql-concatenate-strings-1-2-3-and.html

        避免使用 XML 函数,因为它们性能不佳。

        这需要一些努力来实现,但数百万行 => 运行毫秒。

        【讨论】:

        • @jerry-nixon-msft ,我没有对你投反对票,但我确实在这里看到了一些关于递归 CTE 与 For XML 性能的讨论:stackoverflow.com/questions/13639262/… 看来 For XML 更快在大型数据集上。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-04
        相关资源
        最近更新 更多