[英]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_from
和date_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.