输出大型CSV行的字符串聚合溢出`replace`

时间:2011-09-08 20:14:15

标签: sql string oracle

我从表中选择记录并将结果作为单行CSV列表返回 我正在使用Oracle 10 release 2。这是我的疑问:

SELECT column1,rtrim
           (replace
                (replace
                     (xmlagg(xmlelement("x", column2)).getclobval(), 
                      '<x>',
                      NULL),
                 '</x>',
                 ','),
            ',')
FROM table1
group by column1;

我的问题是,当字符串大于4000个字符时,由于替换功能而失败。我可以通过删除替换功能并使用我的编程语言中的函数来解决这个问题 我想修改查询,以便我可以指定每行返回CSV列表中的元素数量。因此,例如使用上面的查询将返回CSV列表中包含10000个元素的行(不包括替换函数) 修改后的查询将返回10行1000个元素(10行可以修改)。 例如,原始查询将返回:

1234,1234,1234,1234,1234,5678,3456,12344,654677,

修改后的查询类似于

1234,1234,1234,1234,  
1234,5678,3456,12344,  
654677

我不能使用collect函数,但其​​他任何东西都应该是好的,只要SQL可能

1 个答案:

答案 0 :(得分:1)

您可以使用分析函数将行分配给任意存储桶,然后将其分组。

SELECT column1,rtrim
           (replace
                (replace
                     (xmlagg(xmlelement("x", column2)).getclobval(), 
                      '<x>',
                      NULL),
                 '</x>',
                 ','),
            ',')
FROM (SELECT column1, column2, NTILE(10) OVER (PARTITION BY column1 ORDER BY column2) bucket)
group by column1,bucket;

NTILE的参数设置了桶的数量,因此您可以根据需要改变它。

要为每个存储桶设置固定数量的值而不是固定数量的存储桶,我认为您可以用TRUNC( ((ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2)) - 1) /1000 )替换NTILE表达式,其中1000是每个存储桶的值数。