简体   繁体   中英

returning array of rows from psql in window function

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
);

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM