在Oracle中生成连接字符串的快速方法

时间:2011-09-23 14:56:38

标签: sql string oracle connect-by

当邪恶的编码重新出现时,我们不讨厌吗?

前段时间我需要生成一个字符串连接某些字段,以便稍后进行更多处理。我认为如果直接在查询中做,并使用SO的帮助来获得它是一个好主意。有效。有一段时间......

桌子变大了,现在这个技巧(我知道效率极低)并不完全可行。这就是我正在做的事情:

with my_tabe as
(
    select 'user1' as usrid, '1' as prodcode from dual union
    select 'user1' as usrid, '2' as prodcode from dual union
    select 'user1' as usrid, '3' as prodcode from dual union
    select 'user2' as usrid, '2' as prodcode from dual union
    select 'user2' as usrid, '3' as prodcode from dual union
    select 'user2' as usrid, '4' as prodcode from dual
)
select
    usrid,
    ltrim(sys_connect_by_path(prodcode, '|'), '|') as prodcode
from 
    (
    select distinct prodcode, usrid,count(1)
    over (partition by usrid) as cnt,
    row_number() over (partition by usrid order by prodcode) as rn
    from my_tabe 
    )
where
    rn = cnt 
start with rn = 1
connect by prior rn + 1 = rn
and prior usrid = usrid

很好地收益:

USRID   PRODCODE
user1   1|2|3
user2   2|3|4

你可能已经注意到,这里的邪恶之处在于where rn = cnt,如果你删除了,你会看到甲骨文真正在做的所有工作(

USRID   PRODCODE
user1   1
user1   1|2
user1   1|2|3
user2   2
user2   2|3
user2   2|3|4

我实际上在许多我没有太多记录的地方使用它。这是非常好的,大约有50万条记录。

最近我在一张约有15Mi记录的表中尝试了同样的事情,而且......好不好。

问题:有没有办法在Oracle上更有效地执行此操作,还是将时间降低到实际代码? 这不是实际的核心问题,所以我仍然可以负担得起krudging,只要它快速... 值得一提的是我正在使用的“usrid”栏目的索引。

欢呼声,

1 个答案:

答案 0 :(得分:6)

Tom Kyte提供了一种非常方便的方法,它可以在Oracle 9i中使用,具有自定义聚合功能。它与逗号聚合,但您可以修改管道的函数体。

从Oracle 11g开始,您可以:

SELECT LISTAGG(column, separator) WITHIN GROUP (ORDER BY field)
  FROM dataSource
 GROUP BY grouping columns

This web page提供了其他方法,包括您列出的方法以及确实效率不高的方法。