如何在 Oracle10g 中按顺序连接多行
How to concatenate multiple rows order by sequence in Oracle10g
如果我有这样的数据:
GROUP | SEQUENCE | COMMAND
------------------------------
ONE | 3 | <message2>MESSAGE</message2>
ONE | 1 | <?xml version="1.0" encoding="UTF-8"?>
ONE | 2 | <message1>MESSAGE</message1>
TWO | 2 | <message2>MESSAGE</message2>
TWO | 1 | <?xml version="1.0" encoding="UTF-8"?>
........
TWO | 10 | <message9>MESSAGE</message9>
如何将命令连接成这样:
GROUP | COMMAND
-----------------
ONE | <?xml version="1.0" encoding="UTF-8"?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO | <?xml version="1.0" encoding="UTF-8"?>,<message1>MESSAGE</message1>, .. ,<message9>MESSAGE</message9>
我在下面使用了这个查询,但是命令列没有按照它们的序号排列:
SELECT GROUP, WM_CONCAT(COMMAND) AS COMMAND
FROM (SELECT GROUP, SEQUENCE, COMMAND FROM TBL ORDER BY SEQUENCE)
GROUP BY GROUP
//AND THIS
SELECT GROUP, WM_CONCAT(DISTINCT COMMAND) AS COMMAND
FROM (SELECT GROUP, SEQUENCE, COMMAND FROM TBL ORDER BY SEQUENCE)
GROUP BY GROUP
任何意见和建议将不胜感激。 ^_^
永远不要使用 WM_CONCAT
。阅读 Why not use WM_CONCAT function in Oracle?
查看此主题。
它没有记录,任何依赖 WM_CONCAT
的应用程序在升级到 12c
后将无法运行,因为它已从最新的 12c 版本中删除。
根据数据库版本,字符串聚合有很多方法。请参阅以下几个示例:
11gR2
使用LIASTAGG
:
SQL> SELECT grp,
2 listagg(command, ',') WITHIN GROUP(
3 ORDER BY seq) command
4 FROM t
5 GROUP BY grp;
GRP COMMAND
--- --------------------------------------------------------------------------------------------
ONE <?xml version=1.0 encoding=UTF-8?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO <?xml version=1.0 encoding=UTF-8?>,<message2>MESSAGE</message2>,<message9>MESSAGE</message9>
SQL>
9i 及以上
使用ROW_NUMBER()
和SYS_CONNECT_BY_PATH
:
SQL> SELECT grp,
2 LTRIM(MAX(SYS_CONNECT_BY_PATH(command,','))
3 KEEP (DENSE_RANK LAST ORDER BY seq),',') command
4 FROM (SELECT grp,
5 command,
6 seq,
7 ROW_NUMBER() OVER (PARTITION BY grp ORDER BY seq) AS curr,
8 ROW_NUMBER() OVER (PARTITION BY grp ORDER BY seq) -1 AS prev
9 FROM t)
10 GROUP BY grp
11 CONNECT BY prev = PRIOR curr AND grp = PRIOR grp
12 START WITH curr = 1;
GRP COMMAND
--- --------------------------------------------------------------------------------------------
ONE <?xml version=1.0 encoding=UTF-8?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO <?xml version=1.0 encoding=UTF-8?>,<message2>MESSAGE</message2>,<message9>MESSAGE</message9>
SQL>
如果我有这样的数据:
GROUP | SEQUENCE | COMMAND
------------------------------
ONE | 3 | <message2>MESSAGE</message2>
ONE | 1 | <?xml version="1.0" encoding="UTF-8"?>
ONE | 2 | <message1>MESSAGE</message1>
TWO | 2 | <message2>MESSAGE</message2>
TWO | 1 | <?xml version="1.0" encoding="UTF-8"?>
........
TWO | 10 | <message9>MESSAGE</message9>
如何将命令连接成这样:
GROUP | COMMAND
-----------------
ONE | <?xml version="1.0" encoding="UTF-8"?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO | <?xml version="1.0" encoding="UTF-8"?>,<message1>MESSAGE</message1>, .. ,<message9>MESSAGE</message9>
我在下面使用了这个查询,但是命令列没有按照它们的序号排列:
SELECT GROUP, WM_CONCAT(COMMAND) AS COMMAND
FROM (SELECT GROUP, SEQUENCE, COMMAND FROM TBL ORDER BY SEQUENCE)
GROUP BY GROUP
//AND THIS
SELECT GROUP, WM_CONCAT(DISTINCT COMMAND) AS COMMAND
FROM (SELECT GROUP, SEQUENCE, COMMAND FROM TBL ORDER BY SEQUENCE)
GROUP BY GROUP
任何意见和建议将不胜感激。 ^_^
永远不要使用 WM_CONCAT
。阅读 Why not use WM_CONCAT function in Oracle?
查看此主题。
它没有记录,任何依赖 WM_CONCAT
的应用程序在升级到 12c
后将无法运行,因为它已从最新的 12c 版本中删除。
根据数据库版本,字符串聚合有很多方法。请参阅以下几个示例:
11gR2
使用LIASTAGG
:
SQL> SELECT grp,
2 listagg(command, ',') WITHIN GROUP(
3 ORDER BY seq) command
4 FROM t
5 GROUP BY grp;
GRP COMMAND
--- --------------------------------------------------------------------------------------------
ONE <?xml version=1.0 encoding=UTF-8?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO <?xml version=1.0 encoding=UTF-8?>,<message2>MESSAGE</message2>,<message9>MESSAGE</message9>
SQL>
9i 及以上
使用ROW_NUMBER()
和SYS_CONNECT_BY_PATH
:
SQL> SELECT grp,
2 LTRIM(MAX(SYS_CONNECT_BY_PATH(command,','))
3 KEEP (DENSE_RANK LAST ORDER BY seq),',') command
4 FROM (SELECT grp,
5 command,
6 seq,
7 ROW_NUMBER() OVER (PARTITION BY grp ORDER BY seq) AS curr,
8 ROW_NUMBER() OVER (PARTITION BY grp ORDER BY seq) -1 AS prev
9 FROM t)
10 GROUP BY grp
11 CONNECT BY prev = PRIOR curr AND grp = PRIOR grp
12 START WITH curr = 1;
GRP COMMAND
--- --------------------------------------------------------------------------------------------
ONE <?xml version=1.0 encoding=UTF-8?>,<message1>MESSAGE</message1>,<message2>MESSAGE</message2>
TWO <?xml version=1.0 encoding=UTF-8?>,<message2>MESSAGE</message2>,<message9>MESSAGE</message9>
SQL>