Reputation: 155
I am trying to return an array of names as a row in PSQL so that i don't return duplicate entries of data. This is my current query:
SELECT DISTINCT
thread_account.*,
thread.*,
MAX(message.Created) OVER (PARTITION BY thread.id) as Last_Message_Date,
MAX(message.content) OVER (PARTITION BY thread.id) as Last_Message_Sent,
ARRAY_AGG((account.first_name, account.last_name)) OVER (PARTITION BY thread.id) as user
FROM thread_account
JOIN thread on thread.id = thread_account.thread
JOIN message on message.thread = thread_account.thread
JOIN account on account.id = message.account
WHERE thread_account.account = 299
ORDER BY MAX(message.Created) OVER (PARTITION BY thread.id) desc;
any thoughts?
I would like to be able to do something like:
ARRAY_AGG(distinct (account.first_name, account.last_name))
OVER (PARTITION BY thread.id) as user
but it doesn't let you do distinct inside a window function
Here are the table definitions:
create table thread (
id bigserial primary key,
subject text not null,
created timestamp with time zone not null default current_timestamp
);
create table thread_account (
account bigint not null references account(id) on delete cascade,
thread bigint not null references thread(id) on delete cascade
);
create index thread_account_account on thread_account(account);
create index thread_account_thread on thread_account(thread);
create table message (
id bigserial primary key,
thread bigint not null references thread(id) on delete cascade,
content text not null,
account bigint not null references account(id) on delete cascade,
created timestamp with time zone not null default current_timestamp
);
create index message_account on message(account);
create index message_thread on message(thread);
create table account (
id bigint primary key,
first_name text,
last_name text,
email text
);
Upvotes: 2
Views: 2078
Reputation: 273
I don' know why you need the relation thread_account because involved accounts are referenced through messages already.
A possible Query could be:
SELECT DISTINCT
Thread_id,
Thread_Subject,
Thread_Created,
ARRAY_AGG(Message_Account) OVER (PARTITION BY Thread_Id) AS Involed_Accounts,
Last_Message_Date,
Last_Message_Sent
FROM (
SELECT DISTINCT ON (thread.id, message.account)
thread.id AS Thread_Id,
thread.subject AS Thread_Subject,
thread.created AS Thread_Created,
message.account AS Message_Account,
MAX(message.Created)
OVER (PARTITION BY thread.id) AS Last_Message_Date,
MAX(message.content)
OVER (PARTITION BY thread.id) AS Last_Message_Sent
FROM
thread
INNER JOIN message ON (message.thread = thread.id)
INNER JOIN account ON (message.account = account.id)
) as threads
ORDER BY Last_Message_Date desc;
Result:
thread_id | thread_subject | thread_created | Involed_Accounts | last_message_date | last_message_sent
-----------+----------------+-------------------------------+---------------+-------------------------------+-------------------
1 | Thread 1 | 2016-02-17 19:42:58.630795+01 | {1,2,3,4,5,6} | 2016-02-17 19:56:35.749875+01 | R
3 | Thread 3 | 2016-02-17 19:42:58.630795+01 | {1,4,5,8} | 2016-02-17 19:47:27.952065+01 | N
2 | Thread 2 | 2016-02-17 19:42:58.630795+01 | {7,8,9,10} | 2016-02-17 19:47:27.952065+01 | J
You should check the query plan to ensure it performs good on your database.
Upvotes: 2