Создать строку с разделителями из запроса в DB2 - PullRequest
8 голосов
/ 16 сентября 2010

Я пытаюсь создать строку с разделителями из результатов запроса в DB2 на iSeries (AS / 400). Я сделал это в T-SQL, но не могу найти способ сделать это здесь.

Вот мой код в T-SQL. Я ищу эквивлант в DB2.

DECLARE @a VARCHAR(1000)
SELECT @a = COALESCE(@a + ', ' + [Description], [Description])
FROM AP.Checkbooks
SELECT @a

Если описания в моей таблице выглядят так:

Desc 1
Desc 2
Desc 3

Тогда он вернет это:

Desc 1, Desc 2, Desc 3

Ответы [ 4 ]

34 голосов
/ 16 сентября 2010

По сути, вы ищете эквивалент агрегатной функции MySQL GROUP_CONCAT в DB2.Согласно одному потоку, который я нашел , вы можете имитировать это поведение, выполнив функцию XMLAGG:

create table t1 (num int, color varchar(10));

insert into t1 values (1,'red'), (1,'black'), (2,'red'), (2,'yellow'), (2,'green');

select num,
  substr( xmlserialize( xmlagg( xmltext( concat( ', ', color ) ) ) as varchar( 1024 ) ), 3 )
  from t1
  group by num;

Это вернет

1 red,black
2 red,yellow,green

(илидолжен, если я правильно читаю)

1 голос
/ 03 июля 2013

Это можно сделать с помощью общих табличных выражений (CTE) и рекурсии.

with                                                                
    cte1 as                                                             
        (select description, row_number() over() as row_nbr from checkbooks),

    cte2 (list, cnt, cnt_max) AS                              
        (SELECT VARCHAR('', 32000), 0, count(description) FROM cte1
         UNION ALL                                                        
         SELECT 
             -- No comma before the first description
             case when cte2.list = '' THEN RTRIM(CHAR(cte1.description)) 
                  else cte2.list || ', ' || RTRIM(CHAR(cte1.description)) end,   
                  cte2.cnt + 1, 
                  cte2.cnt_max                                
         FROM   cte1,cte2                                                 
         WHERE  cte1.row_nbr = cte2.cnt + 1 AND cte2.cnt < cte2.cnt_max ),                             

    cte3 as                                                          
        (select list from cte2 
         where cte2.cnt = cte2.cnt_max fetch first 1 row only)

select list from cte3;
0 голосов
/ 29 января 2014

Если вы используете DB2 9.7 или новее, вы можете использовать функцию LISTAGG.Посмотрите здесь: http://pic.dhe.ibm.com/infocenter/db2luw/v9r7/index.jsp?topic=%2Fcom.ibm.db2.luw.sql.ref.doc%2Fdoc%2Fr0058709.html

0 голосов
/ 17 сентября 2010

Я пытаюсь сделать это в OLEDB, и, насколько я понимаю, вы не можете сделать это, потому что вы не можете сделать что-то необычное в SQL для OLEDB, как объявление переменных или создание таблицы.Так что я думаю, что нет никакого способа.

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