SQL:在列中使用逗号分隔值合并行

时间:2014-11-11 11:43:15

标签: sql oracle merge split comma

我们有一个这样的表:

Group | User | Team
-------------------
Grp1  | U1   | T1,T2
Grp1  | U2   | T1,T2,T3
Grp1  | U3   | T4
Grp2  | U4   | T2,T4
Grp2  | U5   | T5

我想创建一个包含如下数据的视图:

Group | Teams
-------------
Grp1  | T1,T2,T3,T4
Grp2  | T2,T4,T5

有人可以帮帮我吗?我尝试了一些跟踪和错误,最后我处于一个我甚至不知道从哪里开始的状态

2 个答案:

答案 0 :(得分:0)

这是我的方法。 我正在使用光标,但你也可以在while循环中执行。 唯一的问题是新表中的团队并不明显,但我认为你可以使用字符串命令,它会对问题进行排序。

CREATE TABLE #tbl1 ([GROUP] varchar(20), [USER] VARCHAR(20), team VARCHAR(20))

INSERT INTO #tbl1 ( [GROUP], [USER],team )
VALUES  ( 'Grp1',  'U1',  'T1,T2'),   ( 'Grp1',  'U2',  'T3,T4'),   ( 'Grp1',  'U3',  'T4'),  
( 'Grp2',  'U1',  'T1,T2'),   ( 'Grp2',  'U2',  'T3,T4')

CREATE TABLE #tbl2 ([GROUP] varchar(20), team VARCHAR(20))

DECLARE @ListOfteams VARCHAR(max)
DECLARE @grp VARCHAR(20)
DECLARE Curs CURSOR FAST_FORWARD

    FOR
        SELECT DISTINCT [GROUP]
        FROM #tbl1 AS T

    OPEN Curs
        FETCH NEXT FROM Curs INTO @grp

        WHILE @@FETCH_STATUS = 0

        BEGIN 
            SET @ListOfteams= ''
            SELECT @ListOfteams= @ListOfteams+ [Team] + ',' FROM #tbl1 AS CL WHERE CL.[GROUP] = @grp ORDER BY [CL].[USER]

            INSERT INTO #tbl2   ( [GROUP],team )
            SELECT DISTINCT @grp, 
                        SUBSTRING(@ListOfteams, 1, LEN(@ListOfteams)-1)
            FROM #tbl1 AS T
            WHERE T.[GROUP] = @grp;

            FETCH NEXT FROM Curs INTO @grp
        END
    CLOSE Curs 
    DEALLOCATE Curs;

SELECT * 
FROM #tbl2 AS T

这是有效的:http://rextester.com/BYK57259

+-------+----------------+
| GROUP |      team      |
+-------+----------------+
| Grp1  | T1,T2,T3,T4,T4 |
| Grp2  | T1,T2,T3,T4    |
+-------+----------------+

答案 1 :(得分:0)

以下是如何执行此操作,首先将逗号分隔的团队名称转换为基于其组的各个行,然后使用唯一的团队grp和团队名称。现在将listagg函数应用于唯一的团队名称以实现结果。

    with t as 
(
select 'Grp1' grp,'U1' user1,'T1,T2' team from dual
union all
select 'Grp1','U2','T1,T2,T3' from dual
union all
select 'Grp1','U3','T4' from dual
union all
select 'Grp2','U4','T2,T4' from dual
union all
select 'Grp2','U5','T5' from dual
),
g as
(
select distinct grp, regexp_substr(team,'[^,]+',1,level) team1
from t
connect by level <= LENGTH(REGEXP_REPLACE(team, '[^,]+')) + 1
--group by grp
)
select grp,listagg(team1,',') within group (order by team1) from g
group by grp;

这是我得到的输出

+----+-------------------------------------------+
|GRP ||Teams                                     
+----+-------------------------------------------+
|Grp1|T1,T2,T3,T4                                |
|Grp2|T2,T4,T5                                   |
+----+-------------------------------------------+
相关问题