【问题标题】:how to add uniq in a query如何在查询中添加 uniq
【发布时间】:2019-09-22 10:31:55
【问题描述】:

我有这个

<div>
    <% @readers.each do |reader| %>
        <% user_profile_url = user_url(reader.user.username) %>
        <div>
            <%= link_to user_profile_url do %>
                    <%= reader.user.username %>
            <% end %>
            <span>[<%= reader.created_at.to_date %>]</span>
        </div>
    <% end %>
</div>

在 books_controller 我有这个

  def readers_list
    @book = Book.find(params[:id])
    @readers = @book.downloads.order(created_at: :desc)
  end

我有这个问题:如果用户下载了一本书,在这个列表中我会看到用户名 twince。 所以,我知道,我必须添加 uniq

我尝试将它添加到@readers 的末尾,但没有成功。 如何(以及在​​何处)添加它?!

我也尝试过创建这个@readers = @book.downloads.where(user_id: params[:user_id]).order(created_at: :desc),但没有成功。

【问题讨论】:

  • 你试过了吗? @book.downloads.order(created_at: :desc).distinct
  • @demir 是的。我尝试了 @book.downloads.order(created_at: :desc).distinct 和 @book.downloads.order(created_at: :desc).uniq 但它没有用。我认为因为我正在寻找的“uniq-value”是关于用户,而不是下载
  • book_id 必须在 downloads Schema Information 中。不是最新的?

标签: ruby-on-rails postgresql ruby-on-rails-5


【解决方案1】:

使用DISTINCT 代替uniq。因为你会得到所有东西然后做uniq,这通常被认为是低效的:

book
  .downloads
  .select('distinct on (downloads.user_id) downloads.*')
  .order('downloads.user_id, downloads.created_at DESC')

downloads 被限定为 JOIN 子句,因此 created_at 列存在于两个表中,因此在 select 和 order 中都有显式引用。

【讨论】:

  • order 调用中的 SQL 对我们来说是没有理由的。我会选择.order(:user_id, created_at: :desc) 来达到同样的效果。
  • 你没读过下载的范围是一个 JOIN 子句,所以两个表中都存在 created_at 列 @3limin4t0r?,如果你不添加表名你会有一个模棱两可的错误。您将如何使用 .order(:user_id, created_at: :desc) 指定表名?
  • book.downloads 上下文中,Rails 知道使用下载表。 .order(:user_id, created_at: :desc) 将转换为 ORDER BY "downloads"."user_id", "downloads"."created_at" DESC。我不确定 JOIN 在哪里发挥作用。由于book.downloads 产生SELECT "downloads".* FROM "downloads" WHERE "downloads"."book_id" = «book id»
  • 我知道你的意思@3limin4t0r。在此解决方案的末尾有一条水平线添加了一条消息,解释了为什么我告诉 OP 引用这两个表,而不是仅使用您提出的解决方案。
【解决方案2】:

另一种选择是使用“Group By”,在rails中可以这样做

@book.downloads.order(created_at: :desc).group(:user_id)

如果您想查看“DISTINCT”或“GROUP BY”哪个更快,那么here 是一个不错的起点。

【讨论】:

  • 这是一个 MySQL 基准测试。 OP 正在使用 PostgreSQL(我们在尝试不同的解决方案时遇到了不同的错误)。除非您启用了ONLY_FULL_GROUP_BY,否则不使用id 进行分组会引发错误。
猜你喜欢
  • 2015-02-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-12
  • 1970-01-01
  • 2018-07-05
  • 2019-03-10
相关资源
最近更新 更多