2010-05-13 118 views
3

我们有一点SQL窘境。假设我有一个看起来像这样的结果...SQL 2005将多行合并/连接到一列

61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | B
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | C
61E77D90-D53D-4E2E-A09E-9D6F012EB59C | D
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | E
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | ˚F

是有办法,我可以将SQL中的这些成绩来回报作为

61E77D90-D53D-4E2E-A09E-9D6F012EB59C | A B C D
7ce953ca-a55b-4c55-a52c-9d6f012ea903 | E F

任何想法的人?

非常感谢

戴夫

+0

您应该能够通过合并的东西()与ROW_COUNT做()。我不是TSQL专家,但... – 2010-05-13 16:36:20

回答

1

我更喜欢自定义一个用户定义的聚合。 UDA的Here's an example将完成一些非常接近你的要求。

为什么使用用户定义的聚合而不是嵌套的SELECT?这是关于表现,以及你愿意忍受的。对于少量的元素,您肯定可以逃避嵌套的SELECT,但对于大的“n”,您会注意到查询计划本质上为输出列表中的每一行运行嵌套的SELECT一次。如果你谈论大量的行,这可能是死亡之吻。通过UDA,可以一次性汇总这些值。

当然,折衷是UDA要求您使用CLR来部署它,而这并不是很多人经常做的事情。在Oracle中,这种特定的情况是更好一点,你可以使用PL/SQL directly来创建用户定义的聚合,但我离题...

+0

谢谢,这是我们最好的实施。 – Dave 2010-05-14 07:03:21

+0

我不知道为什么这是倒票,我投了票,因为它似乎是一个合法的(也可能是优雅的)解决方案,它也回答了原来的问题。@Dave - 对于知道*为什么这是最适合你的答案(对于发现这个问题和答案的其他人)会很有用。 – 2010-12-21 21:37:34

+0

谢谢。我对我的回答进行了阐述。看,现在你会downvote它;-) – 2010-12-22 01:57:19

5

试试这个:

set nocount on; 
declare @t table (id char(36), x char(1)) 
insert into @t (id, x) 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'A' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' union 
select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' union 
select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' union 
select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' 
set nocount off 

SELECT p1.id, 
      stuff(
        (SELECT 
         ' ' + x 
         FROM @t p2 
         WHERE p2.id=p1.id 
         ORDER BY id, x 
         FOR XML PATH('') 
        ) 
        ,1,1, '' 
       ) AS YourValues 
     FROM @t p1 
     GROUP BY id 

OUTPUT:

id         YourValues 
------------------------------------ -------------- 
61E77D90-D53D-4E2E-A09E-9D6F012EB59C A B C D 
7ce953ca-a55b-4c55-a52c-9d6f012ea903 E F 

(2 row(s) affected) 

编辑
基于OP的这个需要为现有的查询运行评论,试试这个:

;WITH YourBugQuery AS 
(
    --replace this with your own query 
    select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' AS ColID , 'A' AS ColX 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'B' 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'C' 
    union select '61E77D90-D53D-4E2E-A09E-9D6F012EB59C' , 'D' 
    union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'E' 
    union select '7ce953ca-a55b-4c55-a52c-9d6f012ea903' , 'F' 

) 
SELECT p1.ColID, 
      stuff(
        (SELECT 
         ' ' + ColX 
         FROM YourBugQuery p2 
         WHERE p2.ColID=p1.ColID 
         ORDER BY ColID, ColX 
         FOR XML PATH('') 
        ) 
        ,1,1, '' 
       ) AS YourValues 
     FROM YourBugQuery p1 
     GROUP BY ColID 

这与上面显示的结果集相同。

+1

+1非常好!''' – 2010-05-13 15:47:25

+0

谢谢 - 但我应该指出,结果是从一个SQL查询,所以我不能预测结果将是什么为了让我把他们联合起来。 – Dave 2010-05-13 16:01:10

+0

@Dave,在我的示例代码中,我使用所有的UNION来填充我的表@t,它们与解决方案无关,只是一种将数据导入表中查询的方法。我将编辑问题以使用CTE,因此您可以使其适用于任何查询(第一个示例代码在表格上工作)。 – 2010-05-13 17:12:19

0

做的另一种方法是使用FOR XML PATH选项

SELECT 
    [ID], 
    (
     SELECT 
      [Value] + ' ' 
     FROM 
      [YourTable] [YourTable2] 
     WHERE 
      [YourTable2].[ID] = [YourTable].[ID] 
     ORDER BY 
      [Value] 
     FOR XML PATH('') 
    ) [Values] 
FROM 
    [YourTable] 
GROUP BY 
    [YourTable].[ID]