Clyde
Clyde

Reputation: 11

How to CONCAT and GROUP BY rows in T-SQL

Here is the table I have. Each column is representing as a result of a subquery.

id | A     | B     | C     | (and many columns)
---+-------+-------+-------+----------+--------+-----+-...
 1 | 1a3b  | 1a2b  | 4a1b  |          |
 2 | 7a3b  | 3a7b  | 7a7b  |          |
 3 | 2a3b  | 1a3b  | 3a6b  |          |
 4 | 6a3b  | 6a3b  | 6a3b  |          |

There are many columns in my table, not only A, B and C. The result is generate by CONCAT method.

SELECT CONCAT(A,B,C,...) FROM myTable

That's what I got. Not the answer I want.

id | A     | B     | C     | result        |
---+-------+-------+-------+---------------+
 1 | 1a3b  | NULL  | 4a1b  | 1a3b4a1b      |
 2 | 7a3b  | 3a7b  | 7a3b  | 7a3b3a7b7a3b  |
 3 | 2a3b  | 1a3b  | 3a6b  | 2a3b1a3b3a6b  |
 4 | 6a3b  | 6a3b  | 6a3b  | 6a3b6a3b6a3b  |

I can't find a way to "group by" the rows and get the result like below to remove(or not CONCAT)the repeat value. Is that any way to do that?

id | A     | B     | C     | result        |
---+-------+-------+-------+---------------+
 1 | 1a3b  | NULL  | 4a1b  | 1a3b4a1b      |
 2 | 7a3b  | 3a7b  | 7a3b  | 7a3b3a7b      |
 3 | 2a3b  | 1a3b  | 3a6b  | 2a3b1a3b3a6b  |
 4 | 6a3b  | 6a3b  | 6a3b  | 6a3b          |

Upvotes: 0

Views: 279

Answers (3)

Venkataraman R
Venkataraman R

Reputation: 12989

Below query should work:

DECLARE @table table(id int, a char(4), b char(4), c char(4))

insert into @table values
(2 ,'7a3b','3a7b','7a3b')

SELECT a,b,c, string_agg(t1.dval,'') WITHIN GROUP (ORDER BY a,b,c)) as conc
from @table as ot
CROSS APPLY
(
SELECT DISTINCT val from
(
VALUES
(left(a,2)),
(right(a,2)),
(left(b,2)),
(right(b,2)),
(left(c,2)),
(right(c,2))
)t(val)
) as t1(dval)
group by a,b,c

Upvotes: 0

Zhorov
Zhorov

Reputation: 29993

An approach, based on VALUES table-value constructor and FOR XML, is an option:

Table:

SELECT *
INTO Data
FROM (VALUES
   (1, '1a3b', NULL,   '4a1b'),
   (2, '7a3b', '3a7b', '7a3b'),
   (3, '2a3b', '1a3b', '3a6b'),
   (4, '6a3b', '6a3b', '6a3b')
) v (id, A, B, C)

Statement:

SELECT 
   *,
   result = (
      SELECT DISTINCT CONCAT('', c)
      FROM (VALUES (A), (B), (C)) v (c)
      FOR XML PATH('')   
   )
FROM Data

Result:

id A    B    C    result
-------------------------------
1  1a3b Null 4a1b 1a3b4a1b
2  7a3b 3a7b 7a3b 3a7b7a3b
3  2a3b 1a3b 3a6b 1a3b2a3b3a6b
4  6a3b 6a3b 6a3b 6a3b

Upvotes: 2

Serg
Serg

Reputation: 22811

If I've got it right

select id,A,B,C, string_agg(s, '')
from mytable 
cross apply (
     select distinct s
     from ( values(A),(B),(C)) t(s)
) t(s)
group by id,A,B,C

Upvotes: 1

Related Questions