I am joining 3 tables and getting some duplicated data for certain columns. I want to combine the data to a single row.
The following is the database structure and data.
CREATE TABLE customers (
id integer NOT NULL,
fname character varying(50),
lname character varying(50)
);
COPY customers (id, fname, lname) FROM stdin;
1 Thomas Jefferson
2 Benjamin Franklin
\.
CREATE TABLE customers_products (
id integer NOT NULL,
customers_id integer,
products_id integer,
account_info json
);
COPY customers_products (id, customers_id, products_id, account_info) FROM stdin;
1 1 1 {"account_number":"000001", "date":"05/28/15"}
2 1 2 {"account_number":"000002", "date":"05/28/15"}
3 2 1 {"account_number":"000003", "date":"05/28/15"}
4 2 3 {"account_number":"000004", "date":"05/28/15"}
\.
CREATE TABLE products (
id integer NOT NULL,
name character varying(128)
);
COPY products (id, name) FROM stdin;
1 checking
2 savings
3 credit card
\.
This is the query I'm using.
SELECT
c.id,
c.fname,
c.lname,
p.name,
cp.account_info
FROM
customers c
INNER JOIN
customers_products cp
ON
c.id = cp.customers_id
INNER JOIN
products p
ON
p.id = cp.products_id
This is the resulting dataset.
How would I get the dataset back in 2 rows with the account information combined into single rows? This is the data structure I would like to end up with.
[
{
"id": 1,
"fname": "Thomas",
"lname": "Jefferson",
"account_info": [
{
"name": "checking",
"account_number":"000001",
"date":"05/28/15"
},
{
"name": "savings",
"account_number":"000002",
"date":"05/28/15"
}
]
},
{
"id": 2,
"fname": "Benjamin",
"lname": "Franklin",
"account_info": [
{
"name": "checking",
"account_number":"000003",
"date":"05/28/15"
},
{
"name": "credit card",
"account_number":"000004",
"date":"05/28/15"
}
]
}
]
The solution was:
SELECT
c.id,
c.fname,
c.lname,
string_agg(p.name, ', '),
json_agg(cp.account_info)
FROM
customers c
INNER JOIN
customers_products cp
ON
c.id = cp.customers_id
INNER JOIN
products p
ON
p.id = cp.products_id
GROUP BY
c.id, c.fname, c.lname
ORDER BY
c.id;