【问题标题】:Rails, Count of Users Grouped by created_at day - PostgreSQLRails,按 created_at 天分组的用户计数 - PostgreSQL
【发布时间】:2019-02-18 12:19:01
【问题描述】:

我正在使用 Rails 5,PostgreSQL。我需要使用 postgres DATE_TRUNC 来获取按 created_at 天分组的用户数。 条件是在某个日期范围内创建的用户,并且在同一日期范围内有订单。

以下是导致 AmbiguousFunction 错误的代码

Spree::User.joins(:orders)
           .where(spree_orders: { completed_at: params[:start_date]..params[:end_date] })
           .order("DATE_TRUNC('day', 'created_at')")
           .group("DATE_TRUNC('day', 'created_at')")
           .count

start_date和end_date的参数如下:

params[:end_date] = Time.current.end_of_day
params[:start_date] = (Time.current - 200.days).beginning_of_day

我收到以下错误

ActiveRecord::StatementInvalid: PG::AmbiguousFunction: ERROR: function date_trunc(unknown, unknown) is not unique

甚至当我明确写 spree_users.created_at 我得到同样的错误。

有没有更好的方法来实现这个错误的要求或解决方案?

【问题讨论】:

  • 我不使用 PostgreSQL,但您不应该将 created_at 括在引号中和/或列不明确;试试users.created_at(没有单引号)。
  • 不是为了回答这个问题,但order("DATE_TRUNC('day', 'created_at')")应该是多余的,因为分组和计数。
  • @M.Wyatt 试过了,还是一样的问题

标签: ruby-on-rails ruby postgresql activerecord


【解决方案1】:

ActiveRecord::StatementInvalid: PG::AmbiguousFunction

当我们的查询包含可能属于多个表的列名时会发生此错误。例如,我们有两个表,UserCompany,它们都有一个名为name 的列。现在,以下查询将引发类似于您所面临的错误:

User.joins(:companies).where("name = ABC")

发生这种情况是因为我们没有指定要在哪个表中搜索 name。因此,ActiveRecord 会混淆并且无法创建唯一查询。
在上述情况下,只需将spree_users 附加到ordergroup 查询中使用的created_at 列名即可解决该错误:

Spree::User.joins(:orders)
       .where(spree_orders: { completed_at: params[:start_date]..params[:end_date] })
       .order("DATE_TRUNC('day', 'spree_users.created_at')")
       .group("DATE_TRUNC('day', 'spree_users.created_at')")
       .count

【讨论】:

  • 非常感谢,添加 'spree_users.created_at' 这删除了 ​​AmbiguousFunction 错误。由于默认范围排序与此处按日期排序冲突,因此出现另一个错误,因此添加 unscope(;order) 解决了第二个问题
【解决方案2】:

我认为你可以使用sql中的日期函数来获取时间戳字段的日期,并且由于表User和SpreeOrder都有created_at字段,你应该告知表名(spree_orders.created_at)

Spree::User.joins(:orders)
  .where(spree_orders: { completed_at: params[:start_date]..params[:end_date]})
  .order("date(spree_orders.created_at)")
  .group("date(spree_orders.created_at)")
  .count

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-19
    • 1970-01-01
    • 2013-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    相关资源
    最近更新 更多