X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [200.46.204.144]) by svr1.postgresql.org (Postfix) with ESMTP id 2F70753A93 for ; Sun, 8 May 2005 18:29:11 -0300 (ADT) Received: from svr1.postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 52948-05 for ; Sun, 8 May 2005 21:29:07 +0000 (GMT) Received: from sunsite.dcc.uchile.cl (sunsite.dcc.uchile.cl [192.80.24.2]) by svr1.postgresql.org (Postfix) with ESMTP id A744753A9D for ; Sun, 8 May 2005 18:29:05 -0300 (ADT) Received: from anakena.dcc.uchile.cl (anakena [192.80.24.6]) by sunsite.dcc.uchile.cl (8.13.4/8.12.11) with ESMTP id j48LT5H8013383; Sun, 8 May 2005 17:29:05 -0400 (CLT) Received: by anakena.dcc.uchile.cl (Postfix, from userid 4151) id B06D352927; Sun, 8 May 2005 17:29:05 -0400 (CLT) Date: Sun, 8 May 2005 17:29:05 -0400 From: Alvaro Herrera To: nickf@doxpop.com Cc: pgsql-sql@postgresql.org Subject: Re: interesting SQL puzzle - concatenating column with itself. Message-ID: <20050508212905.GA14422@dcc.uchile.cl> References: <427E60BC.8060701@ontko.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <427E60BC.8060701@ontko.com> User-Agent: Mutt/1.5.8i X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-1.6 (sunsite.dcc.uchile.cl [192.80.24.2]); Sun, 08 May 2005 17:29:05 -0400 (CLT) X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, hits=0.34 tagged_above=0 required=5 tests=AWL, DNS_FROM_RFC_ABUSE X-Spam-Level: X-Archive-Number: 200505/85 X-Sequence-Number: 21398 On Sun, May 08, 2005 at 01:55:56PM -0500, Nick Fankhauser wrote: > > Hi- I'm doing a conversion from an older database in which a memo field was > handled by storing one line per record and then displaying the related > records in order. I want to compress all of the lines into a single text > field with one record per memo entry. > > > So for instance, the old database looks like this: > > > memo_id | sequence | memo_text > --------------------------------------- > 666 | 1 | The quick > 666 | 2 | red fox > 666 | 3 | jumped over > 666 | 4 | the lazy brown dog > > > And my goal is to transform each group of lines into a single record that > looks like this: > > > memo_id | memo_text > ---------------------------------------------------------- > 666 | The quick red fox jumped over the lazy brown dog > > > Any thoughts on how to do this via sql? I could write a little program to > do it, but it seems like there must be a pure-SQL solution that I'm not > seeing. You can create a custom aggregate to do concatenation and group by memo_id. create or replace function text_cat(text, text) returns text called on null input language sql immutable as 'select case when $1 is null then $2 when $2 is null then $1 else $1 || '' '' || $2 end'; create aggregate textcat (basetype = text, sfunc = text_cat, stype = text); create table memos (memo_id int, sequence int, memo_text text); insert into memos values (666, 3, 'jumped over'); insert into memos values (666, 1, 'The quick'); insert into memos values (666, 4, 'the lazy brown dog'); insert into memos values (666, 2, 'red fox'); select memo_id, textcat(memo_text) from (select * from memos order by memo_id, sequence) as foo group by memo_id; The order is not really guaranteed, though if this is a one-shot thing, you may get away with turning off hashed aggregates. -- Alvaro Herrera () "There was no reply" (Kernel Traffic)