3

Possible Duplicate:
How to concatenate strings of a string field in a PostgreSQL ‘group by’ query?

(I'm using postgres)

Are there any aggregate functions that work on strings?

I want to write a query along the lines of

select table1.name, join(' - ', unique(table2.horse)) as all_horses
from table1 inner join table2 on table1.id = table2.fk
group by table1.name

Given these 2 tables:

| table1          |               | table2                    |
| id (pk) | name  |               | id (pk) | horse   |  fk   |
+---------+-------+               +---------+---------+-------+ 
|       1 | john  |               |       1 | redrum  |     1 |
|       2 | frank |               |       2 | chaser  |     1 |
                                  |       3 | cigar   |     2 |

The query should return:

| name   |   all_horses      |
+--------+-------------------+
| john   |   redrum - chaser |
| frank  |   cigar           |

Do functions that along the lines of join and unique exist in any DBs for strings?

Community
  • 1
  • 1
EoghanM
  • 25,161
  • 23
  • 90
  • 123

2 Answers2

14
select table1.name, 
    array_to_string( array_agg( distinct table2.horse ), ' - ' ) as all_horses
from table1 inner join table2 on table1.id = table2.fk
group by table1.name
Michael Buen
  • 38,643
  • 9
  • 94
  • 118
  • hmm don't seem to have those functions defined - can you help me close the question as it's a duplicate of 43870 ? – EoghanM May 17 '10 at 12:10
  • try to upgrade to 8.4, array_agg is built-in. regarding closing the question, it needs 5 close, as of now only 1 closed your question. you can delete your own question – Michael Buen May 17 '10 at 12:22
5

There is a string_agg query in PostreSQL 9. I have a table of regions and a table of departments, where there are multiple departments in a region (e.g. France). My sample query is:

select r.name, string_agg(d.name, ',') 
from regions r
join departments d on d.region = r.code
group by r.name
order by r.name;

This gives me rows like

Picardie Aisne,Oise,Somme

Things get a bit messy if you wan to change the order of the aggregated string. This works, but I have a pathological dislike of any query with distinct:

select distinct r.name as region, string_agg(d.name, ',') over w as departments
from regions r
join departments d on d.region = r.code
window w as (partition by r.name order by d.name desc 
    rows between unbounded preceding and unbounded following)
Bob Folkerts
  • 376
  • 2
  • 11