【发布时间】:2020-05-07 19:44:40
【问题描述】:
以下是Message模型
class Message < ApplicationRecord
belongs_to :parent_message, class_name: 'Message', optional: true
has_many :child_messages, foreign_key: :parent_message_id, class_name: "Message"
has_many :message_participants
scope :latest_messages_by_participant, -> (user_id) do
select("DISTINCT ON (parent_message_id) messages.*").
joins(:message_participants).
where(message_participants: { user_id: user_id }).
order("parent_message_id, created_at DESC")
end
end
message_participants 对每条消息以及发送或接收该消息的各种人都有记录。它上面有一个 user_id。
上述latest_messages_by_participant 范围的问题在于它能够获取所有子消息,但它只获取最后一条父消息。这是因为我们在 parent_message_id 上调用 DISINTICT ON,而对于无子父消息,此值为 NULL,因此它只是在 NULL 上调用 distinct 并返回 1 个值(最后一个无子父消息)。
如何在单个查询中获取所有最新消息,包括最新的子消息和最新的无子父消息?
我正在使用 Rails 6 和 Postgres 11。
PS:我还应该指出一个次要问题,即消息是在 created_at ASC 中返回的。 created_at DESC 能够获取最新的子消息,但不会对整个集合进行排序。我可以通过调用 .reverse 来解决这个问题,但想知道是否也有办法解决这个问题。
【问题讨论】:
-
实际表定义(
CREATE TABLE语句)和一些示例数据将很有帮助。一个普通的 SQL 语句也可以。 -
如果您关心性能,我们需要更多信息。考虑此处的说明:stackoverflow.com/tags/postgresql-performance/info。最重要的是:每个用户和消息 id 上平均有多少行?
-
谢谢@ErwinBrandstetter,目前,性能不是一个考虑因素,但当事情发生变化时肯定会评估。
标签: sql ruby-on-rails postgresql activerecord greatest-n-per-group