Агрегация строк, выводящая большие строки CSV, переполняет `replace` - PullRequest
4 голосов
/ 09 сентября 2011

Я выбираю записи из таблицы и возвращаю результаты в виде списка 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 будет возвращено на строку. Так, например, использование вышеуказанного запроса вернет строку, содержащую 10000 элементов в списке CSV (исключая функцию замены).
Измененный запрос будет возвращать 10 строк по 1000 элементов (10 строк могут быть изменены). например, оригинальный запрос вернет:

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

Исправленный запрос будет выглядеть примерно так:

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

Я не могу использовать функцию collect, но все остальное должно быть хорошо, просто SQL, если это возможно

1 Ответ

1 голос
/ 09 сентября 2011

Вы можете использовать аналитическую функцию, чтобы назначать строки произвольным сегментам и группировать по ним.

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 устанавливает количество сегментов, поэтому вы можете изменять его по мере необходимости.

Чтобы установить фиксированное количество значений для каждого сегмента вместо фиксированного количества сегментов, я думаю, вы могли бы заменить выражение NTILE на TRUNC( ((ROW_NUMBER() OVER (PARTITION BY column1 ORDER BY column2)) - 1) /1000 ), где 1000 - это количество значений в сегменте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...