I have the following data
+--------+ | orders | +--------+ | S1 | | S2 | | S3 | | S4 | | S5 | | S6 | | S7 | | S8 | | S9 | | S10 | | S11 | | S12 | +--------+
I am required to return the result as follows – fit five rows in one column:
+-----------------+ | Orders | +-----------------+ | S1,S2,S3,S4,S5 | | S6,S7,S8,S9,S10 | | S11,S12 | +-----------------+
There is nothing to group on or segregate these into rows. So I assigned a row_number and did mod 5 on the row_number. It almost works, but not quite.
Here is what I have tried:
;with mycte as ( select 'S1' as orders union all select 'S2' union all select 'S3' union all select 'S4' union all select 'S5' union all select 'S6' union all select 'S7' union all select 'S8' union all select 'S9' union all select 'S10' union all select 'S11' union all select 'S12' ) ,mycte2 as ( Select orders ,ROW_NUMBER() over( order by orders) %5 as rownum from mycte ) select distinct STUFF(( SELECT ',' + mycte2.orders FROM mycte2 where t1.rownum= mycte2.rownum FOR XML PATH('') ), 1, 1, '') orders , rownum from mycte2 t1
the result is :
+-----------+--------+ | orders | rownum | +-----------+--------+ | S1,S3,S8 | 1 | | S10,S4,S9 | 2 | | S11,S5 | 3 | | S12,S6 | 4 | | S2,S7 | 0 | +-----------+--------+
Can someone please show me how to get to my desired result?
Advertisement
Answer
How about
CREATE TABLE T ([orders] varchar(3)); INSERT INTO T ([orders]) VALUES ('S1'), ('S2'), ('S3'), ('S4'), ('S5'), ('S6'), ('S7'), ('S8'), ('S9'), ('S10'), ('S11'), ('S12'); WITH CTE AS ( SELECT Orders, (ROW_NUMBER() OVER(ORDER BY LEN(Orders)) - 1) / 5 RN FROM T ) SELECT STRING_AGG(Orders, ',') FROM CTE GROUP BY RN ORDER BY RN;
OR
SELECT STUFF( ( SELECT ',' + Orders FROM CTE WHERE RN = TT.RN FOR XML PATH('') ), 1, 1, '' ) Orders FROM CTE TT GROUP BY RN ORDER BY RN;
You can use
(SELECT 1)
instead ofLEN(Orders)
Returns:
+-----------------+ | Orders | +-----------------+ | S1,S2,S3,S4,S5 | | S6,S7,S8,S9,S10 | | S11,S12 | +-----------------+