需求:
将以下路径明细
ROUTE_ID | ORIGIN | TARGET | ORDER |
1 | A | B | 1 |
1 | B | C | 2 |
1 | C | D | 3 |
2 | A | B | 1 |
2 | B | E | 2 |
拼接成
ROUTE_ID | ROUTE |
1 | A->B->C->D |
2 | A->B->E |
效果
分析:
每条路径明细中包含了起点和终点,我们拼接时只需要取每次的起点使用->连接在一起,再加上最后一行的终点即可。
实现:
1.使用LISTAGG拼接 ORIGIN 列
WITH ROUTE_DATA AS(SELECT 1 AS ROUTE_ID, 'A' AS ORIGIN, 'B' AS TARGET, 1 AS SEQFROM DUALUNION ALLSELECT 1, 'B', 'C', 2FROM DUALUNION ALLSELECT 1, 'C', 'D', 3FROM DUALUNION ALLSELECT 2, 'A', 'B', 1FROM DUALUNION ALLSELECT 2, 'B', 'E', 2FROM DUAL)
SELECT ROUTE_ID,LISTAGG(ORIGIN, '->') WITHIN GROUP(ORDER BY SEQ) AS ROUTEFROM ROUTE_DATAGROUP BY ROUTE_ID;
得到结果:
ROUTE_ID | ROUTE | |
1 | 1 | A->B->C |
2 | 2 | A->B |
2.使用KEEP,获取最后一行数据的 TARGET列并进行拼接
WITH ROUTE_DATA AS(SELECT 1 AS ROUTE_ID, 'A' AS ORIGIN, 'B' AS TARGET, 1 AS SEQFROM DUALUNION ALLSELECT 1, 'B', 'C', 2FROM DUALUNION ALLSELECT 1, 'C', 'D', 3FROM DUALUNION ALLSELECT 2, 'A', 'B', 1FROM DUALUNION ALLSELECT 2, 'B', 'E', 2FROM DUAL)
SELECT ROUTE_ID,LISTAGG(ORIGIN, '->') WITHIN GROUP(ORDER BY SEQ) || '->' || MIN(TARGET) KEEP(DENSE_RANK LAST ORDER BY SEQ) AS ROUTEFROM ROUTE_DATAGROUP BY ROUTE_ID;
得到结果:
ROUTE_ID | ROUTE | |
1 | 1 | A->B->C->D |
2 | 2 | A->B->E |
现在已经达到了我们的效果。
附录:
1.LISTAGG的用法:
LISTAGG
是 Oracle 数据库中用于将多行数据合并为单个字符串的聚合函数。它通常用于将查询结果中的多个值连接成一个逗号分隔的字符串或其他分隔符。
下面是 LISTAGG
函数的基本用法:
LISTAGG(column_name, delimiter) WITHIN GROUP (ORDER BY order_column) AS aggregated_column
column_name
:要合并的列名。delimiter
:用于分隔合并后的值的分隔符,可以是字符串或表达式。order_column
:可选项,指定排序的列名,以确保合并后的字符串顺序正确。aggregated_column
:合并后的结果将放在此列中。
以下是一个示例,假设有一个名为 employees
的表,其中包含 employee_id
和 employee_name
列,你可以使用 LISTAGG
将员工