2010-09-16 8 views
7

Próbuję utworzyć wyodrębniony ciąg z wyników zapytania w DB2 na serwerze iSeries (AS/400). Zrobiłem to w T-SQL, ale nie mogę znaleźć sposobu, aby to zrobić tutaj.Tworzenie oddzielonego ciągu znaków z zapytania w DB2

Oto mój kod w T-SQL. Szukam equivelant w DB2.

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

Jeśli opisy w moim stole wyglądać następująco:

desc 1
opis produktu 2
opis produktu 3

Następnie powróci to:

Desc 1, Desc 2, Desc 3

+0

W MySQL będzie to "GROUP_CONCAT()". –

Odpowiedz

0

I próbuję to zrobić w OLEDB i z tego co rozumiem, nie możesz tego zrobić, ponieważ nie możesz zrobić nic wymyślnego w SQL dla OLEDB jak deklarowanie zmiennych lub tworzenie tabeli. Sądzę więc, że nie ma mowy.

+1

Nie jestem pewien, czy miał to być komentarz do mojej odpowiedzi, ale moja odpowiedź nie deklaruje zmiennych ani nie tworzy tabel. Możliwe jednak, że 'XMLAGG' nie jest dla ciebie dostępna. – CanSpice

+0

Poprawnie, myślę, że nie mam XMLAGG, ponieważ nie rozpoznaje to, co jest w kwerendzie OLEDB. –

+0

Potrafi korzystać z funkcji bazy danych –

31

Zasadniczo szukasz odpowiednika funkcji agregującej MySQL o nazwie GROUP_CONCAT w DB2. Według one thread I found można naśladować to zachowanie, przechodząc przez XMLAGG funkcję:

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; 

byłby to powrót

1 red,black 
2 red,yellow,green 

(lub powinien, jeśli czytam rzeczy poprawnie)

+2

+1, komentarz boczny: Jeśli używasz Z/OS v10, zmień 'jako varchar (1024)' na 'jak clob (1024)' –

+1

Szukałem tego od lat. Działa dokładnie to, czego potrzebuję. Dziękuję Ci. –

1

Można to zrobić, korzystając ze wspólnych wyrażeń tabelowych (CTE) i rekursji.

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; 
Powiązane problemy