sql - Rails - 加入后不同

标签 sql ruby-on-rails postgresql greatest-n-per-group ruby-on-rails-4.2

我将 Rails 4.2 与 PostgreSQL 结合使用。我有一个 Product 模型和一个 Purchase 模型,其中 Product has many Purchases。我想找到不同的最近购买的产品。最初我试过:

Product.joins(:purchases)
.select("DISTINCT products.*, purchases.updated_at") #postgresql requires order column in select
.order("purchases.updated_at DESC")

然而,这会导致重复,因为它会尝试查找对(product.idpurchases.updated_at)具有唯一值的所有元组。但是,我只想在加入后选择具有不同 id 的产品。如果产品 ID 在连接中出现多次,则只选择第一个。所以我也尝试了:

Product.joins(:purchases)
.select("DISTINCT ON (product.id) purchases.updated_at, products.*")
.order("product.id, purchases.updated_at") #postgres requires that DISTINCT ON must match the leftmost order by clause

这不起作用,因为 this,我需要在 order 子句中指定 product.id输出意外顺序的约束。

rails 的实现方式是什么?

最佳答案

基于@ErwinBrandstetter 的回答,我终于找到了正确的方法。查找不同的最近购买的查询是

SELECT *
FROM  (
   SELECT DISTINCT ON (pr.id)
          pu.updated_at, pr.*
   FROM   Product pr
   JOIN   Purchases pu ON pu.product_id = pr.id
   ) sub
ORDER  BY updated_at DESC NULLS LAST;

子查询中不需要 order_by,因为我们无论如何都在外部查询中排序。

rails 的做法是 -

inner_query = Product.joins(:purchases)
  .select("DISTINCT ON (products.id) products.*, purchases.updated_at as date") #This selects all the unique purchased products.

result = Product.from("(#{inner_query.to_sql}) as unique_purchases")
  .select("unique_purchases.*").order("unique_purchases.date DESC")

@ErwinBrandstetter 建议的第二种(也是更好的)方法是

SELECT *
FROM   Product pr
JOIN  (
   SELECT product_id, max(updated_at) AS updated_at
   FROM   Purchases 
   GROUP  BY 1
   ) pu ON pu.product_id = pr.id
ORDER  BY pu.updated_at DESC NULLS LAST;

在rails中可以写成

join_query = Purchase.select("product_id, max(updated_at) as date")
  .group(1) #This selects most recent date for all purchased products

result = Product.joins("INNER JOIN (#{join_query.to_sql}) as unique_purchases ON products.id = unique_purchases.product_id")
  .order("unique_purchases.date")

关于sql - Rails - 加入后不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32775220/

相关文章:

sql - MySQL IN 与 LIKE

jquery - 使用 Rails 3 和 jQuery 进行 Ajax - 从 JS 调用

sql - 识别表中的重复数据

postgresql - 错误 : more than one row returned by subquery

node.js - 使用 Node.js 连接到 Heroku 上的 postgres

sql - 生成多个UPDATE语句并执行它们

sql - 如何在 Oracle 中的字符串中查找精确的字符串匹配

sql - 如何在 VB.NET 中通过 Visual FoxPro 使用 SUM 和 GROUP BY(SQL)?

ruby-on-rails - 使用 MiniTest 检查模型上的方法调用

ruby-on-rails - Rails 4 Assets 管道丢失供应商 Assets