Sql concatenate of row data into column

◇◆丶佛笑我妖孽 提交于 2019-12-22 10:19:39

问题


Data set:

+-----------------+--------+---------+
|     TransNo     | Serial | Project |
+-----------------+--------+---------+
| A00000000000001 |      1 |     100 |
| A00000000000001 |      2 |     200 |
| A00000000000001 |      3 |     201 |
| A00000000000001 |      4 |     101 |
| A00000000000002 |      1 |     100 |
| A00000000000002 |      2 |     101 |
| A00000000000003 |      1 |     100 |
| A00000000000003 |      2 |     200 |
| A00000000000004 |      1 |     200 |
| A00000000000004 |      2 |     100 |
| A00000000000005 |      1 |     101 |
| A00000000000005 |      2 |     100 |
+-----------------+--------+---------+

I want to merge projects in a new column order by project & partition by transaction as following. [Project will be merged by order ASC]

Output:

    +-----------------+--------+---------+------------------+
    |     TransNo     | Serial | Project | CProject         |
    +-----------------+--------+---------+------------------+
    | A00000000000001 |      1 |     100 |     100101200201 |
    | A00000000000001 |      2 |     200 |     100101200201 |
    | A00000000000001 |      3 |     201 |     100101200201 |
    | A00000000000001 |      4 |     101 |     100101200201 |
    | A00000000000002 |      1 |     100 |     100101       |
    | A00000000000002 |      2 |     101 |     100101       |
    | A00000000000005 |      1 |     101 |     100101       |
    | A00000000000005 |      2 |     100 |     100101       |
    | A00000000000003 |      1 |     100 |     100200       |
    | A00000000000003 |      2 |     200 |     100200       |
    | A00000000000004 |      1 |     200 |     100200       |
    | A00000000000004 |      2 |     100 |     100200       |
    +-----------------+--------+---------+------------------+

UPDATE 1:

What to do if I want my output order by Serial instead of project.

    +-----------------+--------+---------+------------------+
    |     TransNo     | Serial | Project | CProject         |
    +-----------------+--------+---------+------------------+
    | A00000000000001 |      1 |     100 |     100200201101|
    | A00000000000001 |      2 |     200 |     100200201101|
    | A00000000000001 |      3 |     201 |     100200201101|
    | A00000000000001 |      4 |     101 |     100200201101|
    | A00000000000002 |      1 |     100 |     100101       |
    | A00000000000002 |      2 |     101 |     100101       |
    | A00000000000005 |      1 |     101 |     101100       |
    | A00000000000005 |      2 |     100 |     101100       |
    | A00000000000003 |      1 |     100 |     100200       |
    | A00000000000003 |      2 |     200 |     100200       |
    | A00000000000004 |      1 |     200 |     200100       |
    | A00000000000004 |      2 |     100 |     200100       |
    +-----------------+--------+---------+------------------+

回答1:


DECLARE @t TABLE (
    TransNo VARCHAR(20),
    Serial INT,
    Project INT
)

INSERT INTO @t (TransNo, Serial, Project)
VALUES
    ('A00000000000001', 1, 100),
    ('A00000000000001', 2, 200),
    ('A00000000000001', 3, 201),
    ('A00000000000001', 4, 101),
    ('A00000000000002', 1, 100),
    ('A00000000000002', 2, 101),
    ('A00000000000003', 1, 100),
    ('A00000000000003', 2, 200),
    ('A00000000000004', 1, 200),
    ('A00000000000004', 2, 100),
    ('A00000000000005', 1, 101),
    ('A00000000000005', 2, 100)

SELECT *, CProject = (
    SELECT DISTINCT [text()] = t2.Project
    FROM @t t2
    WHERE t2.TransNo = t1.TransNo
    ORDER BY t2.Project
    FOR XML PATH('')
)
FROM @t t1

output -

TransNo              Serial      Project     CProject
-------------------- ----------- ----------- --------------
A00000000000001      1           100         100101200201
A00000000000001      2           200         100101200201
A00000000000001      3           201         100101200201
A00000000000001      4           101         100101200201
A00000000000002      1           100         100101
A00000000000002      2           101         100101
A00000000000003      1           100         100200
A00000000000003      2           200         100200
A00000000000004      1           200         100200
A00000000000004      2           100         100200
A00000000000005      1           101         100101
A00000000000005      2           100         100101

with [text()] -

100101200201

without [text()] -

<Project>100</Project><Project>101</Project><Project>200</Project><Project>201</Project>

more details - http://www.codeproject.com/Articles/691102/String-Aggregation-in-the-World-of-SQL-Server

update -

SELECT *, CProject = (
    SELECT [text()] = t2.Project
    FROM (
        SELECT t2.Project, Serial = MIN(t2.Serial)
        FROM @t t2
        WHERE t2.TransNo = t1.TransNo
        GROUP BY t2.Project
    ) t2
    ORDER BY t2.Serial
    FOR XML PATH('')
)
FROM @t t1



回答2:


Try this way

SELECT t1.*,t2.CProject
FROM t AS t1
JOIN (
    SELECT SS.TransNo, (
            SELECT ' ' + US.Project     
            FROM t US
            WHERE US.TransNo = SS.TransNo
            FOR XML PATH('')
        ) CProject
    FROM t SS
    GROUP BY SS.TransNo
    ORDER BY SS.Serial
) t2 ON t1.TransNo = t2.TransNo


来源:https://stackoverflow.com/questions/34505671/sql-concatenate-of-row-data-into-column

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