I have something like this:
id | name | totalAmount |
---|---|---|
1 | name1 | 10 |
2 | name1 | 20 |
3 | name1 | 25 |
4 | name2 | 5 |
5 | name2 | 12 |
And need to looks like this:
id’s | name | totalAmount |
---|---|---|
1,2 | name1 | 30 |
2,3 | name1 | 45 |
1,3 | name1 | 35 |
1,2,3 | name1 | 55 |
4,5 | name2 | 17 |
I’m using the STRING_AGG
but don’t know how to separated in the first 3 id’s.
Advertisement
Answer
Here is a recursive version which can handle more than 3 ids for a name and returns all possible combinations. As Dai points out though, take care as the number of combinations quickly mushrooms. But if your real data is like your example (normally 2-3 ids per name) than it should be fine.
Worth noting that I did this for fun. Probably you would be best just storing the raw data and doing this kind of shenanigans in the application layer.
CREATE TABLE #data ( id INT, [name] VARCHAR(10), totalAmount INT ); INSERT INTO #data VALUES (1, 'name1', 10), (2, 'name1', 20), (3, 'name1', 25), (4, 'name2', 5), (5, 'name2', 12); WITH cte (name, ids, maxid, tot) AS ( SELECT a.name, CONVERT(VARCHAR(8000), CONVERT(VARCHAR(10), a.id) + ',' + CONVERT(VARCHAR(10), b.id) ) AS ids, b.id AS maxid, a.totalAmount + b.totalAmount AS tot FROM #data a INNER JOIN #data b ON b.name = a.name AND a.id < b.id UNION ALL SELECT cte.name, CONVERT(VARCHAR(8000), cte.ids + ',' +CONVERT(VARCHAR(10), a.id)), a.id AS maxid, cte.tot + a.totalAmount FROM cte INNER JOIN #data a ON cte.name = a.name WHERE a.id > cte.maxid ) SELECT ids, name, tot FROM cte