【问题标题】:Postgres Rails Select Distinct with OrderPostgres Rails 选择 Distinct with Order
【发布时间】:2013-01-09 06:14:36
【问题描述】:

这似乎比应该做的更难:

我希望能够通过它的 copy_count 对表进行排序,然后仅选择具有唯一标题的事件,并将该查询限制为前 99 个。

 Event.order("copy_count DESC").select("DISTINCT ON (events.title) *").limit(99)

这会引发错误:

ActiveRecord::StatementInvalid: PG::Error: ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions

这建议我需要将 copy_count 添加到 DISTINCT ON,但这也只会拉回可能相同的唯一 copy_count 记录!

注意:必须先按 copy_count 排序。

谢谢

【问题讨论】:

  • 那么,你想要 99 个events.title 最高的copy_count 而没有重复的events.title?

标签: sql ruby-on-rails postgresql


【解决方案1】:

对于纯 SQL,它看起来像:

SELECT *
FROM (SELECT DISTINCT ON (events.title) *
      FROM events
      ORDER BY events.title, events.copy_count DESC) top_titles
ORDER BY events.copy_count DESC
LIMIT 99

但我不知道,如何在 RoR 中编写它。

【讨论】:

  • 将其转换为 AR/Arel 语法会很棒。
  • 是的,这个问题确实指定了 Rails - 有人知道如何使用 AR Query 界面指定这个吗?
【解决方案2】:

试试这个:

Event.select("DISTINCT ON (events.title) *").order("events.title, copy_count DESC").limit(99)

这是因为当您使用语句 DISTINCT ON 时,您必须在 ORDER BY 表达式中使用其表达式(例如 events.title)

SQL ERROR:  SELECT DISTINCT ON expressions must match initial ORDER BY expressions 

因此,您只需在订单语句中的 events.title 之后添加 copy_count 列

【讨论】:

    【解决方案3】:

    试试这个:

    Event.order("copy_count DESC").limit(99).select(:title).uniq
    

    【讨论】:

    • uniq is deprecated and will be removed from Rails 5.1 (use distinct instead)
    【解决方案4】:

    表示 ORDER BY 需要为“events.title, copy_count DESC”。 DISTINCT ON 要求您排序的第一件事是 DISTINCT 列的列表。如果您试图获得每个标题的最高结果,则必须先将它们分组为具有相同标题的行集,然后才能按 copy_count 排序。如果这不是您想要做的,那么 DISTINCT ON 不是正确的构造。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 2021-02-10
      • 2016-10-31
      相关资源
      最近更新 更多