0

Suppose I have this table:

a   b   c
-----------
1   a   d
2   a   d
3   b   d
4   b   d
5   c   e
6   c   e

Is there a way that I could group by b and c and get a concatenated value for matching a's?

Like this:

a   b   c
-----------
1,2 a   d
3,3 b   d
5,6 c   e

I can get one a by using GROUP BY:

SELECT MAX(a) AS a, b, c 
FROM mytable 
GROUP BY b, c

but that is not what I am looking for...

2
  • 1
    @GuidoG - This isn't a pivot. They want to generate a delimited list. OP - What version of sql server are you using? Commented Jun 7, 2018 at 15:36
  • Version 10.50.2500.0 Commented Jun 8, 2018 at 7:37

3 Answers 3

2

Isnt this a simple STUFF concatenation?

DECLARE @MYTAB TABLE (ID INT,
                      ONE NVARCHAR(1),
                      TWO NVARCHAR(1)
                     )

INSERT INTO @MYTAB VALUES
(1, 'a', 'd'),
(2, 'a', 'd'),
(3, 'b', 'd'),
(4, 'b', 'd'),
(5, 'c', 'e'),
(6, 'c', 'e')


SELECT STUFF(
(
    SELECT N', '+CAST(ID AS NVARCHAR(50))
    FROM @MYTAB T2
    WHERE T2.ONE = T.ONE
          AND T2.TWO = T.TWO FOR XML PATH(''), TYPE
).value('text()[1]', 'nvarchar(max)'), 1, 2, N'') [MY AGGREGATE],
       ONE,
       TWO
FROM @MYTAB T
GROUP BY T.ONE,
         T.TWO;

SQL SERVER 2017:

SELECT  STRING_AGG(CAST(ID AS nvarchar(50)), ', '),
        ONE,
        TWO
FROM @MYTAB
GROUP BY ONE, TWO

Output:

AGG     ONE TWO
---------------
1, 2    a   d
3, 4    b   d
5, 6    c   e
Sign up to request clarification or add additional context in comments.

2 Comments

Never heard of the "stuff" before and was unable to find it easily :(
glad to help then :)
1

This should solve your problem

create table #t 
(
    a char(1)
    ,b char(1)
    ,c char(1) 
)

insert into #t
select '1','a','d' union all 
select '2','a','d' union all 
select '3','b','d' union all 
select '4','b','d' union all 
select '5','c','e' union all 
select '6','c','e' 

select stuff ((select ','+ a FROM #t T1 where T1.b = T.B and T1.c = T.c For XML  PATH ('')) ,1,1,''),b,c
FROM #t T 
group by b,c 

Comments

1

Stuff is the best solution I agree.
Just to give you another option you can also do it without stuff

declare @t table (a int, b varchar(1), c varchar(1))
insert into @t values (1, 'a', 'd'), (2, 'a', 'd'), (3, 'b', 'd'), (4, 'b', 'd'), (5, 'c', 'e'), (6, 'c', 'e')

select left(temp.a, len(temp.a) - 1) as a, 
       temp.b, 
       temp.c
from   ( select t.b, 
                t.c,
                ( select convert(varchar, t2.a) + ',' AS [text()]
                  from   @t t2
                  where  t2.b = t.b
                  and    t2.c = t.c
                  For XML PATH ('')
                ) as a
         from   @t t
         group by t.b, t.c
       ) temp 

this would give you the same result as stuff but is much more complex off course

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.