【问题标题】:How to get value using join table with different values?如何使用具有不同值的连接表获取值?
【发布时间】:2019-11-02 07:12:56
【问题描述】:

我有一个产品、用户和 product_click 模型。 在 product_click 中,我有列 count 我在其中记录了哪个用户点击了哪个产品多少次。

我也试过

Product.sort_by{ |r|  r.product_clicks.where(user_id: user.id).first.try(:count).to_i

它给出了期望的结果,但在运行时会产生大量查询。

product_click.rb

belongs_to :product
  belongs_to :user

产品.rb

has_many :product_clicks, dependent: :destroy

用户.rb

has_many :product_clicks, dependent: :destroy

架构

create_table "product_clicks", force: :cascade do |t|
    t.bigint "product_id"
    t.bigint "user_id"
    t.bigint "count", default: 0
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

在控制器中

Product.left_outer_joins(:product_clicks).order("count DESC NULLS LAST")

现在我正在寻找这样的工作。

但在这里我无法检查计数是否属于哪个特定用户。 如果我要添加

Product.left_outer_joins(:product_clicks).where(resource_clicks: { user_id: user.id }).order("count DESC NULLS LAST")

然后它显示用户点击的产品,但不是“零”产品(我从未点击过)。

我也试过了

Product.left_outer_joins(:product_clicks).where(product_clicks: { user_id: [user.id, nil] }).order("count DESC NULLS LAST")

但给了我我点击的所有内容以及其他人没有点击的所有内容。如果有人点击了我没有点击,那么它不会显示给我。

【问题讨论】:

  • 您的预期输出是什么?我的意思是,不清楚你想展示什么。可以添加product_clicks 的列吗?如果是连接表,考虑添加has_many through关系。 resource_clicks 是什么?
  • @iGian 嗨,更新了问题。感谢您的反馈。我希望当前正在访问该应用程序的特定用户对具有最大点击产品的产品进行排序。
  • @T J 有参考资料吗?
  • @philipxy 长话短说,我需要对点击次数最多的产品进行排序。以及存储在 Product_click 表中的用户点击次数。我想在下面显示该特定用户的分类产品和其余产品。很快我会更新这个问题。谢谢。

标签: sql ruby-on-rails postgresql ruby-on-rails-5 left-join


【解决方案1】:

虽然我在考虑其他方法,但直接的方法是两步解决方案。

product_ids = ProductClick.where(user_id: user.id).order('count desc').pluck(:product_id)

products = Product.where(id: product_ids)

它肯定会节省您的时间,并且比您的查询(N+1)更好。

使用预加载

Product.includes(:product_clicks).where('product_clicks.user_id' => user.id).order('product_clicks.count desc')

上面的查询也应该以相同的方式产生,但是,无论如何它可能会在内部遇到 2 个查询。

使用having子句 - 推荐

Product.includes(:product_clicks).having('product_clicks.user_id' => user.id).order('product_clicks.count desc')

更新 - 使用 OR

Product.includes(:product_clicks).where('product_clicks.user_id' => user.id)
       .order('product_clicks.count desc')
       .or(
        Product.includes(:product_clicks)
               .where('product_clicks.user_id' => user.id)
               .where(product_clicks: { id: nil })
       )

【讨论】:

  • @Farhan 感谢您抽出宝贵的时间,我可以存档您要解释的内容,但这里的问题是,我没有得到用户从未点击过的产品。
  • 同样的事情发生了,Product.includes(:product_clicks).where('product_clicks.user_id' => user.id).order('product_clicks.count desc') 它没有显示其他用户点击但我没有点击的产品。
  • @AnshulRiyal 我已经用新的查询更新了答案。不幸的是,我没有类似的模式来测试它,如果有错误或什么,请尝试让我知道。
猜你喜欢
  • 1970-01-01
  • 2015-06-07
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 2022-01-13
  • 2021-12-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多