I'm working with PostgreSQL customer records.

My task is to export customer records.

I have another table aside from customers with contact information.

One contact item per line (phone, value or email, value, etc.).

When I join and relate the data, I pull multiple records per customer ID (if more than 1 comm type for each customer, example phone and email).

How could I instead of making another row for each comm type, put the info into a temporary column like a phone column, a fax column, and an email column -- then have only 1 row for each customer.

edit -- you guys are masters

Database tables w/ columns:

account {
  id
  accountid
  title (company name?)
  shiptoaddress_id (links to address table)
  billtoaddress_id (links to address table)
}

address {
  city
  country
  state
  name (company name?)
  street1
  street2
  street3
  zip
  id
}

comlink {
  isdeleted
  type [Phone,Fax,E-mail,Cell,IM,FaceBook,Twitter,LinkedIn,Web Site,Other]
  value
  id
  party_id (links to party table)
}

party {
  isdeleted [t,f]
  firstname
  lastname
  prefix
  salutation
  suffix
  id
  address_id
  jobtitle_id
}

party_comlinks {
  party_id (links to party table ex: fname lname...)
  comlinks_id (links to comlink table phone, email, etc 1 item per row)
}

So what I want to do is pull all customers with the following data:

customer.id, customer.accountid, customer.title, shipping.name, shipping.street1, shipping.street2, shipping.street3, shipping.city, shipping.state, shipping.zip, billing.name, billing.street1 (etc), billing.city, billing.state, billing.zip, party.contactperson (as party.firstname + party.lastname) AND have phone, email, fax

I'm not sure if this will be possible as in the system I think you can have multiple shipping info, billing info, contact info for each customer... however where each shipping info and billing info is the same, I only want one row of phone, email, fax, etc and not multiple rows for each phone, email, fax, etc.

Clear as mud, right? :-)

edit -- may have gotten it now, but would still appreciate input

SELECT account.id, account.accountid, account.status, account.title AS "customer",
party.firstname AS "firstname", party.lastname as "lastname", address.name AS "billname",
address.street1 AS "billtostreet1", address.street2 AS "billtostreet2", address.city as "billtocity",
address.state AS "billtostate", address.zip AS "billtozip", address2.name AS "shiptoname",
address2.street1 as "shiptostreet1", address2.street2 AS "shiptostreet2", address2.city AS "shiptocity",
address2.state AS "shiptostate", address2.zip AS "shiptozip", 

((SELECT a.value 
FROM public.comlink a, party_comlinks b
WHERE b.party_id=party.id AND b.comlinks_id=a.id AND a.type='Phone')) AS "phone",

((SELECT a.value 
FROM public.comlink a, party_comlinks b
WHERE b.party_id=party.id AND b.comlinks_id=a.id AND a.type='Fax')) AS "fax",

((SELECT a.value 
FROM public.comlink a, party_comlinks b
WHERE b.party_id=party.id AND b.comlinks_id=a.id AND a.type='E-Mail')) AS "email"

FROM  ( public.account account 
   INNER JOIN public.party party ON account.contact_id = party.id )  
   INNER JOIN public.comlink comlink ON party.id = comlink.party_id 
   INNER JOIN public.address address ON account.billtoaddress_id = address.id
   INNER JOIN public.contact contact ON account.contact_id = contact.id
   LEFT JOIN public.contact_shiptoaddress contact_shiptoaddress ON contact.id = contact_shiptoaddress.contact_id
   LEFT JOIN public.address address2 ON contact_shiptoaddress.shiptoaddress_id = address2.id



WHERE account.isdeleted = 'f'

--WHERE ((comlink.type = 'E-Mail')) 
    --AND ((account.walkin is null OR (NOT ( account.walkin ))))
    --AND ((NOT ( (account."status" = 'CustomerStatusInactive') )))
    --AND ((account."prospect" is null
    --OR (NOT ( account."prospect" )))) 

ORDER BY account.id ASC

Actually, the INNER JOIN's were not what I needed... I needed to do LEFT JOIN's as described below.

  • Can you show us an example of the data, what query you've tried, and what correct results would look like? – jmelesky May 26 '16 at 20:09
  • Add the definition of the tables (as create table statements). Some sample data and the expected output based on that data. Formatted text please, no screen shots – a_horse_with_no_name May 26 '16 at 20:09
up vote 0 down vote accepted

You'll have to do this by explicitly joining against the contact table multiple times. There is now way to have a "dynamic" set of output columns depending on the data.

Example:

SELECT customers.name, phone_contacts.value AS phone, fax_contacts.value AS fax, ...
FROM customers
  LEFT JOIN (SELECT * FROM contacts WHERE contact_type = 'phone') AS phone_contacts ON ...
  LEFT JOIN (SELECT * FROM contacts WHERE contact_type = 'fax') AS fax_contacts ON ...
  • 1
    LEFT JOIN (SELECT * FROM contacts WHERE contact_type = 'phone') can be simplified to LEFT JOIN contacts ON contact_type = 'phone' AND ... – a_horse_with_no_name May 26 '16 at 20:19
  • This is a good example, I might be able to experiment with this a bit, but not absolutely positive if it will work or not. – swam May 26 '16 at 20:34

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.