问题
I need an active record query that returns the count of Parents with a Child created within a date range AND a Child created prior to the date range.
I currently have the following two queries: This query returns the count of Parents with a Child created within the date range
Parent.joins(:children).where("children.created_at BETWEEN ? AND ?", start, end).distinct.count(parent_id)
This query counts the Parents with a Child created before the date range
Parent.joins(:children).where("children.created_at < ?", start).distinct.count(:parent_id)
I need to find the count of Parents that have a Child created within the range AND a Child created before the range.
How is the best way to get this result?
回答1:
You can do this in following ways,
Simple way, get the ids for parent from the first query and apply the filter on parent id in second query,
q1_pids = Parent.joins(:children)
.where("children.created_at BETWEEN ? AND ?", start, end)
.ids
count = Parent.joins(:children)
.where("children.created_at < ?", start)
.where(id: q1_pids)
.count("parents.id")
Using INTERSECT
q1 = Parent.joins(:children)
.where("children.created_at BETWEEN ? AND ?", start, end)
q2 = Parent.joins(:children)
.where("children.created_at < ?", start)
count = (q1 & q1).count
Second solution just uses array intersection, however you can prepare the SQL statement yourself to fire a single SQL query to the database.
回答2:
Extending @Sujan's answer, you can fetch all the records in a single query as well.
Parent.joins(:children)
.joins('INNER JOIN children AS before_start_children ON before_start_children.parent_id = parents.id')
.where(children: {created_at: start..end})
.where("before_start_children.created_at < ?", start)
.distinct
.count(parent_id)
来源:https://stackoverflow.com/questions/58308005/active-record-query-to-find-parents-with-child-within-a-date-range-and-child-pri