以更高效的方式从 PostgreSQL 数据库中检索数据
Retrieving data from PostgreSQL DB in a more efficient way
我正在使用 PostgreSQL 开发实时聊天应用程序,但遇到以下问题:
当用户登录时,我需要获取所有不是登录用户的用户,以便将它们显示在应用程序的侧边栏上。
每个用户下方应显示已登录用户或其他用户发送的最新消息。
我正在尝试执行高效查询,以便立即检索所有用户及其最新消息,但没有成功。
这是我的表格:
我最初尝试做类似的事情:
SELECT users.id, users.first_name, users.last_name, users.image, messages.sender_id, messages.recipient_id, messages.content
FROM users LEFT JOIN messages on users.id = messages.sender_id OR users.id = messages.recipient_id
WHERE (messages.sender_id = 1 OR messages.recipient_id = 1) AND users.id != 1
GROUP BY users.id
ORDER BY messages.created_at DESC;
我得到了这个错误:
- “1”指登录用户id
我的临时解决方案是从数据库中获取所有用户,在服务器上映射它们并执行另一个查询,该查询使用 - ORDER BY created_at DESC LIMIT 1 发回用户之间的最新消息。
我相信还有更有效的方法,如果有任何帮助,我将不胜感激!
如果我没听错,你可以使用条件逻辑 select 在 logged-in 用户和任何其他用户之间交换(发送或接收)的消息,然后加入对应的用户记录。要获得每个用户的最新消息,distinct on
在 Postgres 中很方便。
考虑:
select distinct on (u.id) u.id, ... -- enumerate the columns you want here
from (
select m.*,
case when sender_id = 1 then recipient_id else sender_id end as other_user_id
from messages m
where 1 in (m.sender_id, m.recipient_id)
) m
inner join users u on u.id = m.other_user_id
order by u.id, m.created_at desc
我们也可以用横向连接来表达:
select distinct on (u.id) u.id, ...
from messages m
cross join lateral (values
(case when sender_id = 1 then recipient_id else sender_id end as other_user_id)
) as x(other_user_id)
inner join users u on u.id = x.other_user_id
where 1 in (m.sender_id, m.recipient_id)
order by u.id, m.created_at desc
我正在使用 PostgreSQL 开发实时聊天应用程序,但遇到以下问题:
当用户登录时,我需要获取所有不是登录用户的用户,以便将它们显示在应用程序的侧边栏上。
每个用户下方应显示已登录用户或其他用户发送的最新消息。
我正在尝试执行高效查询,以便立即检索所有用户及其最新消息,但没有成功。
这是我的表格:
我最初尝试做类似的事情:
SELECT users.id, users.first_name, users.last_name, users.image, messages.sender_id, messages.recipient_id, messages.content
FROM users LEFT JOIN messages on users.id = messages.sender_id OR users.id = messages.recipient_id
WHERE (messages.sender_id = 1 OR messages.recipient_id = 1) AND users.id != 1
GROUP BY users.id
ORDER BY messages.created_at DESC;
我得到了这个错误:
- “1”指登录用户id
我的临时解决方案是从数据库中获取所有用户,在服务器上映射它们并执行另一个查询,该查询使用 - ORDER BY created_at DESC LIMIT 1 发回用户之间的最新消息。
我相信还有更有效的方法,如果有任何帮助,我将不胜感激!
如果我没听错,你可以使用条件逻辑 select 在 logged-in 用户和任何其他用户之间交换(发送或接收)的消息,然后加入对应的用户记录。要获得每个用户的最新消息,distinct on
在 Postgres 中很方便。
考虑:
select distinct on (u.id) u.id, ... -- enumerate the columns you want here
from (
select m.*,
case when sender_id = 1 then recipient_id else sender_id end as other_user_id
from messages m
where 1 in (m.sender_id, m.recipient_id)
) m
inner join users u on u.id = m.other_user_id
order by u.id, m.created_at desc
我们也可以用横向连接来表达:
select distinct on (u.id) u.id, ...
from messages m
cross join lateral (values
(case when sender_id = 1 then recipient_id else sender_id end as other_user_id)
) as x(other_user_id)
inner join users u on u.id = x.other_user_id
where 1 in (m.sender_id, m.recipient_id)
order by u.id, m.created_at desc