簡體   English   中英

Rails 中的 ActiveRecord 查詢

[英]ActiveRecord querying in Rails

我不知道如何實現以下規范而不訴諸使用 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_fromdate_to是從報表中刪除的日期參數。

我希望可能有一種方法來簡化這個?

您當前的方法將所有訂單都放入內存中,這會很慢而且很崩潰。 我會這樣做:

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)

請參考鏈接

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM