我需要检索与特定用户交换过消息的所有用户的列表,以及最后发送的消息的时间戳和收到的最后一条消息的时间戳。我想在单个查询中执行此操作。
结果将是这样的:
[
[0] {
:uname => "fred",
:last_received => 2013-04-09 22:47:20 UTC,
:last_sent => 2013-04-09 22:47:28 UTC
},
[1] {
:uname => "barney",
:last_received => nil,
:last_sent => 2013-06-16 16:25:56 UTC
},
[2] {
:uname => "dino",
:last_received => 2013-06-09 17:52:54 UTC,
:last_sent => 2013-06-10 15:56:52 UTC
}
]
简化的模式是:
CREATE TABLE users (
id serial NOT NULL,
uname text NOT NULL,
created_at timestamp without time zone DEFAULT timezone('utc'::text, now())
)
CREATE TABLE messages (
id serial NOT NULL,
sender_id integer NOT NULL,
recipient_id integer NOT NULL,
message_text_id integer,
created_at timestamp without time zone DEFAULT timezone('utc'::text, now())
)
我有一个执行此操作的查询,但由于它确实在用户上留下了连接,我担心它会随着用户数量的增加而变慢——我不知道 postgresql 是否会对其进行优化以避免这种情况发生。
WITH t AS (
select sender_id, recipient_id, max(created_at) as latest_date
from messages
where sender_id = #{id} or recipient_id = #{id}
group by sender_id, recipient_id
)
select uname, t1.latest_date last_received, t2.latest_date last_sent
from users
left join t t1 on t1.sender_id = users.id and t1.sender_id != #{id}
left join t t2 on t2.recipient_id = users.id and t2.recipient_id != #{id}
where t1.latest_date is not null or t2.latest_date is not null
我有兴趣了解 postgresql 是否会对此进行优化,并希望了解执行相同查询的更好方法。
谢谢。马克