我正在尝试为特定用户选择所有主题主题,但我想通过最近的线程通过最近发送的消息进行排序。这是我的数据库架构。
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);
然后我正在进行像
这样的查询select *
FROM thread_account
JOIN thread on thread.id = thread_account.thread
JOIN message on message.thread = thread_account.thread
WHERE thread_account.account = 299
ORDER BY message.created desc;
但是这只是为每个有消息的条目提供了所有主题主题的列表。 (message.thread = thread_account.thread上的JOIN消息)似乎是个问题。我被告知我需要一个窗口功能,但似乎无法弄清楚它们。这是Postgres的方式。
答案 0 :(得分:0)
我认为你正在寻找类似的东西:
select *
FROM thread_account
JOIN thread on thread.id = thread_account.thread
JOIN message on message.thread = thread_account.thread
WHERE thread_account.account = 299
ORDER BY MAX(message.Created) OVER (PARTITION BY thread.id) desc;
小调整是ORDER BY中的窗口函数。这将按thread.id
对结果集进行分区,因此您最终会得到每个thread.id
的记录块,然后它会为每个记录块找到max(message.created)
。然后它使用max(message.created)
对结果集进行排序。
窗口函数一开始就很难处理,但只需将它们视为分块记录(分区),然后将某种聚合或函数应用于该块中的某个字段,例如{ {1}}。
正如评论中所提到的,您不希望看到消息的信息,而只是线程。您只需在查询的Max()
部分中指定结果集中所需的字段。您可以使用SELECT
或GROUP BY
为每个帖子获取一条记录。
此外,我们可以通过将该窗口函数复制到DISTINCT
部分来显示结果中的最后消息日期:
Select
如果您只想要SELECT DISTINCT
thread_account.*,
thread.*,
MAX(message.Created) OVER (PARTITION BY thread.id) as Last_Message_Date
FROM thread_account
JOIN thread on thread.id = thread_account.thread
JOIN message on message.thread = thread_account.thread
WHERE thread_account.account = 299
ORDER BY MAX(message.Created) OVER (PARTITION BY thread.id) desc;
或Thread
中的某些字段,那么您只需在查询的Thread_Account
部分中更加明确,例如SELECT
答案 1 :(得分:0)
非常方便distinct on
让事情变得简单:
select distinct on (t.id) *
from
thread_account ta
inner join
thread t on t.id = ta.thread
inner join
message m on m.thread = ta.thread
where ta.account = 299
order by t.id, m.created desc
仅对线索信息执行:
select distinct on (t.id) t.*