如何对表进行分组,同时将每个组中的所有列值保存为单个列作为逗号分隔值

时间:2015-02-19 08:58:21

标签: sql sql-server performance tsql sql-server-2012

请参阅以下SQL代码。

Declare @LookUp table (id int,val varchar(12))
insert into @LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')

Declare @summary table (id int,val varchar(2000))
------------------------------
Declare @value varchar(30) 
Declare @start int = 1, @end int = (Select count(Distinct id) from @LookUp)

While @start <= @end
Begin
    Set @value = ''
    Select @value = @value + '|' + val From @LookUp Where id = @start

    Insert into @summary 
    Select @start,Right(@value,Len(@value)-1)

    Set @start = @start + 1
End

Select * From @summary

使用以下查询,我将基于Id进行分组,并将组中的值作为逗号分隔值进行分组。

输入:

enter image description here

输出:

enter image description here

我使用循环来完成此操作,当涉及到大量数据时,循环效果不佳。

我们可以避免循环吗?

注意:假设@ lookup.id是连续的。

5 个答案:

答案 0 :(得分:2)

INSERT @summary(id, val)
SELECT
  t.id, 
  STUFF(( 
        select '|' + [val] 
        from @LookUp t1 
        where t1.id = t.id 
        for xml path(''), type 
    ).value('.', 'varchar(max)'), 1, 1, '') [values] 
FROM @LookUp t 
GROUP BY t.id 

答案 1 :(得分:2)

试试这个..

 Declare @LookUp table (id int,val varchar(12))
   insert into @LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')

    select
        id,
        val = 
            stuff((
                select
                    '| ' + t2.val
                from @LookUp t2
                where
                    t2.id = t1.id
                group by t2.val
                for xml path(''), type).value('.', 'varchar(max)'
            ), 1, 2, '')
    from @LookUp t1
    GROUP BY t1.id

答案 2 :(得分:2)

Declare @LookUp table (id int,val varchar(12))
insert into @LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F');


WITH A AS
(
    SELECT DISTINCT id
    FROM @LookUp
)
SELECT 
    A.id, 
    STUFF
    (
        (
            SELECT  ',' + val 
            FROM    @LookUp B
            WHERE B.id = A.id
            FOR XML PATH('')
        ),
        1, 1, ''
    ) AS val
FROM A

答案 3 :(得分:2)

Declare @LookUp table (id int,val varchar(12))
insert into @LookUp values (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')


SELECT DISTINCT a.id, stuff((select '|' + val
                      from @LookUp c 
                      where c.id = a.id 
                      for xml path('')),1,1,'') as vall
FROM @LookUp a

答案 4 :(得分:2)

我将添加一个基于递归公用表表达式的解决方案。通过少量修改,它也应该在DB2中工作(您必须将row_number()函数更改为rownumber()以及连接如何在第二个列表中工作(使用||而不是concat功能)。

DECLARE @LookUp TABLE (id int, val varchar(12))
INSERT INTO @LookUp VALUES (1,'A'),(1,'D'),(1,'X'),(2,'B'),(2,'F')

;WITH
    list1(rn, id, val) AS
    ( 
      SELECT row_number() OVER (PARTITION BY id ORDER BY id), id, val
      FROM @LookUp
    ),
    list2 (id, val, idx) AS
    ( 
      SELECT id, val, 1
      FROM list1
      WHERE rn = 1
      UNION ALL
      SELECT 
       list2.id, 
      CAST(CONCAT(list2.val, ' | ', list1.val) AS varchar(12)), 
       list2.idx + 1
      FROM list2
     JOIN list1 ON list2.id = list1.id 
      WHERE list2.idx + 1 = list1.rn
    )


SELECT l2.id, l2.val
FROM list2 l2
JOIN (SELECT id, MAX(rn) maxid FROM list1 GROUP BY id) a 
ON l2.id = a.id AND l2.idx = a.maxid
ORDER BY l2.id

输出:

id  val
1   A | D | X
2   B | F