How do I aggregate data from multiple rows into a delimited list?

Started by D. Dante Lorensoalmost 19 years ago5 messagesgeneral
Jump to latest
#1D. Dante Lorenso
dante@larkspark.com

I want to select several rows of data and have them returned in a single
record with the rows joined by a delimiter. It would be great if this
could be done in a generic way possibly using the GROUP BY like this:

SELECT a.id, a.name, STR_SUM(b.name, ',') AS b_names
FROM a, b
WHERE a.id = b.id
GROUP BY a.id, a.name;

Sample data would look like this:

[table a]
id | name
----+------
1 | one
2 | two
3 | three
4 | four

[table b]
id | name
----+------
1 | pizza
1 | hot dog
2 | gorilla
2 | monkey
3 | apple
4 | cheese
4 | milk
4 | eggs

And the result would look like this:

id | name | b_names
----+-------+---------
1 | one | pizza,hot dog
2 | two | gorilla,monkey
3 | three | apple
4 | four | cheese,milk,eggs

The STR_SUM function above would be some aggregate that just joins
records together using concatenation. If the function can't be used as
an aggregate, I suppose I could just use a sub-select:

SELECT a.id, a.name, (
SELECT STR_SUM(b.name, ',')
FROM b
WHERE b.id = a.id) AS b_names
FROM a;

Does my made-up function "STR_SUM" exist in PostgreSQL already? Has
anyone written one they could share? I'm fairly capable with PL/PGSQL
and could write a function to loop through records and concate onto a
string, but before I brute-force this one, I was hoping to find
something more elegant preferred by the community.

Thanks,

-- Dante

#2Gunzler
geoff.kloess@gmail.com
In reply to: D. Dante Lorenso (#1)
Re: How do I aggregate data from multiple rows into a delimited list?

On Jul 1, 3:09 pm, d...@larkspark.com ("D. Dante Lorenso") wrote:

I want to select several rows of data and have them returned in a single
record with the rows joined by a delimiter. It would be great if this
could be done in a generic way possibly using the GROUP BY like this:

I recently wrote this to address the same need. I practically copied
it straight from the "CREATE AGGREGATE" documentation, so look there
for more information. It will create a "text_accumulate" aggregate
function that does what you need:

CREATE FUNCTION text_append(text,text) RETURNS text
AS 'select $1 || '','' || $2;'
LANGUAGE SQL
IMMUTABLE
RETURNS NULL ON NULL INPUT;

CREATE AGGREGATE text_accumulate(
BASETYPE = text,
SFUNC = text_append,
STYPE = text
);

Geoff

#3Berend Tober
btober@ct.metrocast.net
In reply to: D. Dante Lorenso (#1)
Re: How do I aggregate data from multiple rows into a delimited list?

D. Dante Lorenso wrote:

I want to select several rows of data and have them returned in a
single record with the rows joined by a delimiter.

Review the User Comments at

"http://www.postgresql.org/docs/8.0/interactive/sql-createaggregate.html"

for some ideas.

#4Chris
dmagick@gmail.com
In reply to: D. Dante Lorenso (#1)
Re: How do I aggregate data from multiple rows into a delimited list?

D. Dante Lorenso wrote:

I want to select several rows of data and have them returned in a single
record with the rows joined by a delimiter.

I have something like that here:

http://www.designmagick.com/article/38

--
Postgresql & php tutorials
http://www.designmagick.com/

#5D. Dante Lorenso
dante@lorenso.com
In reply to: Berend Tober (#3)
Re: How do I aggregate data from multiple rows into a delimited list?

Berend Tober wrote:

D. Dante Lorenso wrote:

I want to select several rows of data and have them returned in a
single record with the rows joined by a delimiter.

Review the User Comments at
"http://www.postgresql.org/docs/8.0/interactive/sql-createaggregate.html"
for some ideas.

I found a better solution using ARRAY_TO_STRING and ARRAY. My question
email was originally blocked because I sent it to the list from the
wrong email address. Unfortunately it was later unfrozen and sent on to
the list (sorry) because I did more searching and had solved the problem
on my own:

http://archives.postgresql.org/pgsql-general/2007-07/msg00075.php

Thanks for all your help, though!

-- Dante