通过 Oracle 连接
Concatenate Over Oracle
这是样本table数据
Fruit Number
Apple 1
Apple 2
Apple 3
Kiwi 6
Kiwi 10
我尝试连接 table 列值以获得以下内容
Fruit Number
Apple 1-2-3
Kiwi 6-10
有没有办法查询这个或存储过程?
像 Concatenate over(partition by) 这样的东西,我对存储过程了解不多。谢谢!
您不需要存储过程。使用listagg
函数:
select fruit, listagg(number, ',') within group (order by number)
from mytable
group by fruit
如果你的数据库版本是10g还是很简单的:使用WM_CONCAT
(如果不认识名字可能试试WMSYS.WM_CONCAT
)函数,请参阅 this 答案中的示例。以防万一您需要使用不同于 ,
的分隔符,您可以将结果包装在 replace
函数中;如果您想对结果进行排序,只需在子查询中对其进行预排序,例如:
select fruit, replace(wm_concat(number), ',', '-')
from (select fruit, number
from mytable
order by number)
group by fruit
如果您出于某种神秘原因在您的实例中没有该功能,您可以使用 polyfill,请参阅我的回答 here。
OP 在 Oracle 10g 上,LISTAGG 在 11g 第 2 版 中引入。
因此,在 11g 之前的 Oracle 版本 中 LISTAGG
不受支持,您可以使用 ROW_NUMBER() 和 SYS_CONNECT_BY_PATH 函数。
SELECT fruit,
LTRIM(MAX(SYS_CONNECT_BY_PATH(number,','))
KEEP (DENSE_RANK LAST ORDER BY curr),',') AS fruits_agg
FROM (SELECT fruit,
number,
ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) AS curr,
ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) -1 AS prev
FROM table_name)
GROUP BY fruit
CONNECT BY prev = PRIOR curr AND fruit = PRIOR fruit
START WITH curr = 1;
注意
切勿使用 WM_CONCAT
,因为它是一个未记录的功能,并且已从 12c 版本中删除。
任何一直依赖 wm_concat
功能的应用程序在升级到 12c
后将无法运行。从那以后,它已被删除。参见 Why not use WM_CONCAT function in Oracle?
SQL> select banner from v$version where rownum = 1;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
SQL> SELECT object_name
2 FROM dba_objects
3 WHERE owner='WMSYS'
4 AND object_name LIKE 'WM\_%' ESCAPE '\';
OBJECT_NAME
----------------------------------------------------------------------------
WM_REPLICATION_INFO
WM_RDIFF
WM_PERIOD
WM_PERIOD
WM_OVERLAPS
WM_MEETS
WM_LESSTHAN
WM_LDIFF
WM_INTERSECTION
WM_INSTALLATION
WM_GREATERTHAN
WM_EVENTS_INFO
WM_ERROR
WM_ERROR
WM_EQUALS
WM_DDL_UTIL
WM_DDL_UTIL
WM_CONTAINS
WM_COMPRESS_BATCH_SIZES
WM_COMPRESSIBLE_TABLES
20 rows selected.
SQL>
您将收到“无效标识符”错误:
SQL> SELECT banner FROM v$version;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE 12.1.0.1.0 Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production
SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
*
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier
因此,没有必要依赖未记录的功能,该功能在最新版本中不再可用。
这是样本table数据
Fruit Number
Apple 1
Apple 2
Apple 3
Kiwi 6
Kiwi 10
我尝试连接 table 列值以获得以下内容
Fruit Number
Apple 1-2-3
Kiwi 6-10
有没有办法查询这个或存储过程? 像 Concatenate over(partition by) 这样的东西,我对存储过程了解不多。谢谢!
您不需要存储过程。使用listagg
函数:
select fruit, listagg(number, ',') within group (order by number)
from mytable
group by fruit
如果你的数据库版本是10g还是很简单的:使用WM_CONCAT
(如果不认识名字可能试试WMSYS.WM_CONCAT
)函数,请参阅 this 答案中的示例。以防万一您需要使用不同于 ,
的分隔符,您可以将结果包装在 replace
函数中;如果您想对结果进行排序,只需在子查询中对其进行预排序,例如:
select fruit, replace(wm_concat(number), ',', '-')
from (select fruit, number
from mytable
order by number)
group by fruit
如果您出于某种神秘原因在您的实例中没有该功能,您可以使用 polyfill,请参阅我的回答 here。
OP 在 Oracle 10g 上,LISTAGG 在 11g 第 2 版 中引入。
因此,在 11g 之前的 Oracle 版本 中 LISTAGG
不受支持,您可以使用 ROW_NUMBER() 和 SYS_CONNECT_BY_PATH 函数。
SELECT fruit,
LTRIM(MAX(SYS_CONNECT_BY_PATH(number,','))
KEEP (DENSE_RANK LAST ORDER BY curr),',') AS fruits_agg
FROM (SELECT fruit,
number,
ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) AS curr,
ROW_NUMBER() OVER (PARTITION BY fruit ORDER BY number) -1 AS prev
FROM table_name)
GROUP BY fruit
CONNECT BY prev = PRIOR curr AND fruit = PRIOR fruit
START WITH curr = 1;
注意
切勿使用 WM_CONCAT
,因为它是一个未记录的功能,并且已从 12c 版本中删除。
任何一直依赖 wm_concat
功能的应用程序在升级到 12c
后将无法运行。从那以后,它已被删除。参见 Why not use WM_CONCAT function in Oracle?
SQL> select banner from v$version where rownum = 1;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
SQL> SELECT object_name
2 FROM dba_objects
3 WHERE owner='WMSYS'
4 AND object_name LIKE 'WM\_%' ESCAPE '\';
OBJECT_NAME
----------------------------------------------------------------------------
WM_REPLICATION_INFO
WM_RDIFF
WM_PERIOD
WM_PERIOD
WM_OVERLAPS
WM_MEETS
WM_LESSTHAN
WM_LDIFF
WM_INTERSECTION
WM_INSTALLATION
WM_GREATERTHAN
WM_EVENTS_INFO
WM_ERROR
WM_ERROR
WM_EQUALS
WM_DDL_UTIL
WM_DDL_UTIL
WM_CONTAINS
WM_COMPRESS_BATCH_SIZES
WM_COMPRESSIBLE_TABLES
20 rows selected.
SQL>
您将收到“无效标识符”错误:
SQL> SELECT banner FROM v$version;
BANNER
----------------------------------------------------------------------------
Oracle Database 12c Enterprise Edition Release 12.1.0.1.0 - 64bit Production
PL/SQL Release 12.1.0.1.0 - Production
CORE 12.1.0.1.0 Production
TNS for 64-bit Windows: Version 12.1.0.1.0 - Production
NLSRTL Version 12.1.0.1.0 - Production
SQL> SELECT deptno, wm_concat(ename) FROM emp;
SELECT deptno, wm_concat(ename) FROM emp
*
ERROR at line 1:
ORA-00904: "WM_CONCAT": invalid identifier
因此,没有必要依赖未记录的功能,该功能在最新版本中不再可用。