Обсуждение: How do I aggregate data from multiple rows into a delimited list?
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
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.
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/
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
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