SQL Server 2016 - Five Column to single row

牧云@^-^@ 提交于 2020-01-06 08:10:32

问题


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?


回答1:


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 of LEN(Orders)

Returns:

+-----------------+
|     Orders      |
+-----------------+
| S1,S2,S3,S4,S5  |
| S6,S7,S8,S9,S10 |
| S11,S12         |
+-----------------+

Demo



来源:https://stackoverflow.com/questions/53715205/sql-server-2016-five-column-to-single-row

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!