【问题标题】:ActiveRecord querying in RailsRails 中的 ActiveRecord 查询
【发布时间】:2016-03-18 15:14:56
【问题描述】:

我不知道如何在不使用 Ruby 进行映射/选择等的情况下实现以下规范,并尝试尽可能多地使用 SQL。

我的“公司”有很多“员工”。

公司的一名员工被标记为“联系人”(布尔字段)。映射到范围contact_points。

公司也有很多“订单”。

挑战是查询某个时间段内的所有联络点员工,并返回公司在此期间下达第一笔订单的员工。

因此,这是查找订单的最短 created_at 时间的组合,按 company_id 分组,然后返回公司寻找联络点员工。 (我认为)。

经过大量尝试使用纯 ActiveRecord/SQL 解决方案的喘息和喘息之后,我求助于这个。

Employee
  .contact_points
  .joins(:company)
  .where(
    companies: {
      id: Order.all.group_by(&:company_id)
            .map{ |o| o.last.sort{ |a,b| a.created_at <=> b.created_at }.first }
            .keep_if{ |o| (date_from..date_to).cover?(o.created_at) }
            .map(&:company_id)
    }
  )

date_from 和 date_to 是从报告表单中删除的日期参数。

我希望有办法简化这个?

【问题讨论】:

    标签: ruby-on-rails ruby postgresql activerecord


    【解决方案1】:

    您当前的方法将所有订单吸入内存,这将是缓慢且崩溃的。我会这样做:

    Employee
      .contact_points
      .joins(:company)
      .where(<<-EOQ, date_from, date_to, date_from)
        EXISTS (SELECT  1 
                FROM    orders o
                WHERE   o.company_id = companies.id
                AND     o.created_at BETWEEN ? AND ?)
        AND NOT EXISTS (SELECT  1
                        FROM    orders o
                        WHERE   o.company_id = companies.id
                        AND     o.created_at < ?)
      EOQ
    

    其实除非有其他条件你甚至不需要加入companies,因为你可以使用employees.company_id。

    编辑:或者这可能更高效:

    Employee
      .contact_points
      .joins(<<-EOQ)
        INNER JOIN (SELECT o.company_id, MIN(o.created_at) created_at
                    FROM   orders o
                    GROUP BY company_id) min_orders
        ON employees.company_id = min_orders.company_id
      EOQ
      .where("min_orders.created_at BETWEEN ? AND ?", date_from, date_to)
    

    【讨论】:

    • 保罗,谢谢你,我用了第二个例子,它很管用!感谢您的帮助。
    【解决方案2】:

    请参考链接

    http://guides.rubyonrails.org/active_record_querying.html

    SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5))

    【讨论】:

    • 所以链接只是参考,代码行就是答案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-15
    • 2015-12-21
    • 1970-01-01
    相关资源
    最近更新 更多