![]() | |
![]() |
| | Thread Tools | Display Modes |
#1
| |||
| |||
|
#2
| |||
| |||
|
|
Need some help with the following example. I have email, people and people2email tables. The people2email table is a one-to-many with one person able to have many email addresses, and the people_with_email view ties it all together for me. Here's the output when I do a "select * from people_with_email;" first_name | last_name | email_address ------------+------------+-------------------------- Scott | Goodwin | scott (AT) scottg (DOT) tv Fred | Flintstone | fred.flintstone (AT) blah (DOT) com Barney | Rubble | barney (AT) hodown (DOT) com Barney | Rubble | barney.rubble (AT) hey (DOT) org What I really want is one person per row, with the email addresses concat'd together with commas, like this: |
|
first_name | last_name | email_address ------------+------------+-------------------------- Scott | Goodwin | scott (AT) scottg (DOT) tv Fred | Flintstone | fred.flintstone (AT) blah (DOT) com Barney | Rubble | barney (AT) hodown (DOT) com, barney.rubble (AT) hey (DOT) org My question is: how do I modify the select statement that generates the people_with_email view so that it generates the output I want? I'll gladly tie myself to any PG-specific feature that does the job as I'll not be moving to any other database software within my lifetime if I can help it (and I can . I wouldn't mind using arrays, but can'treally change the data type of a column in a view (is there a way to CAST it?). Might be able to use a materialized view, which could then support array columns, but I'd be satisfied with a plain text string that I can split on with Tcl. The datamodel, with the view and dummy data is below. thanks, /s. ======== data model ========= drop view people_with_email; drop table people2email; drop table email; drop table people; create table email ( email_id integer primary key, email_address varchar(128) not null unique ); copy email from stdin with delimiter '|'; 1|scott (AT) scottg (DOT) tv 2|fred.flintstone (AT) blah (DOT) com 3|barney (AT) hodown (DOT) com 4|barney.rubble (AT) hey (DOT) org \. create table people ( person_id integer primary key, first_name varchar(32) not null, last_name varchar(32) not null ); copy people from stdin with delimiter '|'; 1|Scott|Goodwin 2|Fred|Flintstone 3|Barney|Rubble \. create table people2email ( person_id integer references people (person_id), email_id integer references email (email_id) ); copy people2email from stdin with delimiter '|'; 1|1 2|2 3|3 3|4 \. create view people_with_email as select a.first_name, a.last_name, b.email_address from people a inner join people2email r on a.person_id = r.person_id inner join email b on b.email_id = r.email_id ; ---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend |
#3
| |||
| |||
|
|
Need some help with the following example. I have email, people and people2email tables. The people2email table is a one-to-many with one person able to have many email addresses, and the people_with_email view ties it all together for me. Here's the output when I do a "select * from people_with_email;" first_name | last_name | email_address ------------+------------+-------------------------- Scott | Goodwin | scott (AT) scottg (DOT) tv Fred | Flintstone | fred.flintstone (AT) blah (DOT) com Barney | Rubble | barney (AT) hodown (DOT) com Barney | Rubble | barney.rubble (AT) hey (DOT) org What I really want is one person per row, with the email addresses concat'd together with commas, like this: first_name | last_name | email_address ------------+------------+-------------------------- Scott | Goodwin | scott (AT) scottg (DOT) tv Fred | Flintstone | fred.flintstone (AT) blah (DOT) com Barney | Rubble | barney (AT) hodown (DOT) com, barney.rubble (AT) hey (DOT) org My question is: how do I modify the select statement that generates the people_with_email view so that it generates the output I want? I'll gladly tie myself to any PG-specific feature that does the job as I'll not be moving to any other database software within my lifetime if I can help it (and I can . I wouldn't mind using arrays, but can'treally change the data type of a column in a view (is there a way to CAST it?). Might be able to use a materialized view, which could then support array columns, but I'd be satisfied with a plain text string that I can split on with Tcl. The datamodel, with the view and dummy data is below. thanks, /s. ======== data model ========= drop view people_with_email; drop table people2email; drop table email; drop table people; create table email ( email_id integer primary key, email_address varchar(128) not null unique ); copy email from stdin with delimiter '|'; 1|scott (AT) scottg (DOT) tv 2|fred.flintstone (AT) blah (DOT) com 3|barney (AT) hodown (DOT) com 4|barney.rubble (AT) hey (DOT) org \. create table people ( person_id integer primary key, first_name varchar(32) not null, last_name varchar(32) not null ); copy people from stdin with delimiter '|'; 1|Scott|Goodwin 2|Fred|Flintstone 3|Barney|Rubble \. create table people2email ( person_id integer references people (person_id), email_id integer references email (email_id) ); copy people2email from stdin with delimiter '|'; 1|1 2|2 3|3 3|4 \. create view people_with_email as select a.first_name, a.last_name, b.email_address from people a inner join people2email r on a.person_id = r.person_id inner join email b on b.email_id = r.email_id ; ---------------------------(end of broadcast)--------------------------- TIP 8: explain analyze is your friend |
#4
| |||
| |||
|
#5
| |||
| |||
|
|
drop view people_with_email; drop table people2email; drop table email; drop table people; drop aggregate concatenate(text); drop function join_with_comma(text,text); create function join_with_comma(text,text) returns text immutable strict language 'sql' as 'select $1||'', ''||$2' ; create aggregate concatenate ( sfunc = join_with_comma, basetype = text, stype = text ); create table email ( email_id integer primary key, email_address text not null unique ); copy email from stdin with delimiter '|'; 1|scott (AT) scottg (DOT) tv 2|fred.flintstone (AT) blah (DOT) com 3|barney (AT) hodown (DOT) com 4|barney.rubble (AT) hey (DOT) org \. create table people ( person_id integer primary key, first_name text not null, last_name text not null ); copy people from stdin with delimiter '|'; 1|Scott|Goodwin 2|Fred|Flintstone 3|Barney|Rubble \. create table people2email ( person_id integer references people (person_id), email_id integer references email (email_id) ); copy people2email from stdin with delimiter '|'; 1|1 2|2 3|3 3|4 \. create view people_with_email as select a.first_name, a.last_name, c.email_address from people a, (select r.person_id, concatenate(b.email_address) as email_address from people2email r, email b where r.email_id = b.email_id group by r.person_id) as c where a.person_id = c.person_id ; |
![]() |
| Thread Tools | |
| Display Modes | |
| |