Connecting Tech Pros Worldwide Forums | Help | Site Map

Aggregate/concatenate function (flattening columns into a row)

Newbie
 
Join Date: May 2007
Posts: 6
#1: Jun 12 '07
Hi Forum,

I'm trying to perform a type of concatenate function on a table and am not really sure where to start. I'd like to aggregate the values from 'field' on their ID. To explain, my table is like this:

ID roadnum
1 A-1
2 B-1
2 E-1
3 N-1
4 N-3
4 E-2
4 CA-1
5 E-1

Which I'd like to transform to:

ID roadnum
1 A-1
2 B-1 / E-1
3 N-1
4 E-2 / CA-1 / N-3
5 E-1

I've been looking at various lists and forums but I've not been able to follow the explanations. Further down the line, instead of simply concatenating the field values, I'd like to concatenate according to the road importance- which is based on the roadnum, but one step at a time. When I have the values in the same field, I'll worry about the next step.

Matt

shoonya's Avatar
Familiar Sight
 
Join Date: May 2007
Location: india
Posts: 159
#2: Jun 14 '07

re: Aggregate/concatenate function (flattening columns into a row)


Quote:

Originally Posted by mattdoughty

Hi Forum,

I'm trying to perform a type of concatenate function on a table and am not really sure where to start. I'd like to aggregate the values from 'field' on their ID. To explain, my table is like this:

ID roadnum
1 A-1
2 B-1
2 E-1
3 N-1
4 N-3
4 E-2
4 CA-1
5 E-1

Which I'd like to transform to:

ID roadnum
1 A-1
2 B-1 / E-1
3 N-1
4 E-2 / CA-1 / N-3
5 E-1

I've been looking at various lists and forums but I've not been able to follow the explanations. Further down the line, instead of simply concatenating the field values, I'd like to concatenate according to the road importance- which is based on the roadnum, but one step at a time. When I have the values in the same field, I'll worry about the next step.

Matt

you can use the array data tye
make the roadnum attribute an array and append the routes in the last
check array data type from postgreSQL documentation

but be careful as when you will select the array from databse using php or ny other language it will return only a string {value1,value2...}
so iterate nd make it an array

shoonya
Moderator
 
Join Date: Nov 2006
Location: Boston, USA
Posts: 505
#3: Jun 14 '07

re: Aggregate/concatenate function (flattening columns into a row)


This should work for you

Expand|Select|Wrap|Line Numbers
  1. CREATE or replace FUNCTION flatten() RETURNS integer AS $$
  2. DECLARE
  3.     rec RECORD ;
  4.     cnt integer ;
  5.     delim varchar := '/';
  6. BEGIN
  7.      FOR rec IN SELECT * FROM tab1 ORDER BY ID LOOP
  8.         select count(1) into cnt from tab2 where tab2.ID = rec.ID;
  9.         if cnt = 0 then
  10.            insert into tab2 values (rec.ID, rec.roadnum);
  11.         else
  12.            update tab2 set roadnum = roadnum || delim || rec.roadnum 
  13.                where tab2.ID = rec.ID;
  14.         end if;
  15.     END LOOP;
  16.  
  17.     RETURN (select count (*) from tab2);
  18. END;
  19. $$ LANGUAGE plpgsql;
  20.  
here's the result of running select flatten();
Expand|Select|Wrap|Line Numbers
  1. postgres=# select * from tab1;
  2.   id   | roadnum
  3. -------+-----
  4.      1 | A1
  5.      2 | B1
  6.      2 | B2
  7.      3 | C1
  8.      3 | C2
  9.      3 | C3
  10.      4 | D1
  11.      4 | D2
  12.      4 | D3
  13.      4 | D4
  14.      5 | E1
  15.      6 | F1
  16.      7 | G1
  17.      7 | G2
  18.      8 | J1
  19.      8 | J2
  20.      9 | H1
  21.     10 | K1
  22. (18 rows)
  23.  
  24.  
  25. postgres=# select * from tab2;
  26.  id    | roadnum
  27. -------+-------------
  28.      1 | A1
  29.      2 | B1/B2
  30.      3 | C1/C2/C3
  31.      4 | D1/D2/D3/D4
  32.      5 | E1
  33.      6 | F1
  34.      7 | G1/G2
  35.      8 | J1/J2
  36.      9 | H1
  37.     10 | K1
  38. (10 rows)
  39.  
Newbie
 
Join Date: Aug 2008
Posts: 1
#4: Aug 8 '08

re: Aggregate/concatenate function (flattening columns into a row)


You may find this useful:
Expand|Select|Wrap|Line Numbers
  1. SELECT array_to_string(array(SELECT column_name FROM table_name), ':');
  2.  
Change the inner SELECT to any query that returns only one column.
This will concatenate all values into one string, with a ':' between each value.

Expand|Select|Wrap|Line Numbers
  1. SELECT array_to_string(array(SELECT roadnum FROM table_name WHERE ID=4), ':');
  2.  
would return "N-3:E-2:CA-1" .

Powerful!
Reply