Postgresql 将SQL转换为Arel-列[…]必须出现在GROUP BY子句中

Postgresql 将SQL转换为Arel-列[…]必须出现在GROUP BY子句中,postgresql,arel,Postgresql,Arel,我有一个正在工作的SQL查询,我想将其转换为Arel,但我似乎一直遇到相同的错误 工作SQL: 尝试1不工作 orders = Order.arel_table Order .where.not(restaurant_id: nil) .select(:restaurant_id) .select(:date) .select(Order.arel_table[:order_number].count.as('order_count')) .select

我有一个正在工作的SQL查询,我想将其转换为Arel,但我似乎一直遇到相同的错误

工作SQL:

尝试1不工作

orders = Order.arel_table

Order
    .where.not(restaurant_id: nil)
    .select(:restaurant_id)
    .select(:date)
    .select(Order.arel_table[:order_number].count.as('order_count'))
    .select(
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
    )
    .group(
        :restaurant_id, 
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]), 
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
    )
orders = Order.arel_table
query = orders
      .where(orders[:restaurant_id].not_eq(nil))
      .project(
          orders[:restaurant_id],
          Order.arel_table[:order_number].count.as('order_count'),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
      )
      .group(
          orders[:restaurant_id],
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
      )
      .order(orders[:date].desc)
      .to_sql
Order.find_by_sql(query)
尝试2不工作

orders = Order.arel_table

Order
    .where.not(restaurant_id: nil)
    .select(:restaurant_id)
    .select(:date)
    .select(Order.arel_table[:order_number].count.as('order_count'))
    .select(
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
    )
    .group(
        :restaurant_id, 
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]), 
        Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
    )
orders = Order.arel_table
query = orders
      .where(orders[:restaurant_id].not_eq(nil))
      .project(
          orders[:restaurant_id],
          Order.arel_table[:order_number].count.as('order_count'),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
      )
      .group(
          orders[:restaurant_id],
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
          Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
      )
      .order(orders[:date].desc)
      .to_sql
Order.find_by_sql(query)
这两种方法都会导致以下错误:

PG::GroupingError:ERROR:列orders.date必须出现在GROUP BY子句中或在聚合函数中使用

问题是我不想按日期分组,而是按月份分组。关于如何解决这个问题有什么建议吗

我最初也尝试过Arel::Nodes::NamedFunction.new'date\u part',['month',:date]而不是Arel::Nodes::NamedFunction.new'date\u part',[Arel::Nodes.build\u quoted'month',orders[:date]],但结果如下:

不支持的参数类型:字符串。而是构造一个Arel节点


非常感谢您的帮助。谢谢

所以经过几个小时的挖掘,它终于找到了答案!我的问题之一是在我的订单模型上设置了一个默认的_范围,这就是按日期排序的地方。最后,我决定删除默认作用域,在实际需要的位置使用排序,我在查询中只剩下以下内容:

orders = Order.arel_table
query = orders
  .where(orders[:restaurant_id].not_eq(nil))
  .project(
      orders[:restaurant_id],
      Order.arel_table[:order_number].count.as('order_count'),
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
  )
  .group(
      orders[:restaurant_id],
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
  )
  .order(
      orders[:restaurant_id],
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
      Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc

  )
  .to_sql

Order.find_by_sql(query)
经验教训:尽可能避免使用默认的\u范围。如果你一个人工作,你很可能会忘记你用过它。如果你在一个团队中工作,你可能只需要花费某人一整天的时间