我对我正在尝试编写的查询有点迷失。正如问题所述,我试图从表中返回所有记录,该表至少有 5 个满足特定条件的关联记录。具体来说,我有汽车和司机。一个司机可以拥有很多辆车,我想返回所有在 3 周前创建的至少拥有 5 辆车的司机。
下面的查询为我提供了在过去 3 周内至少创建了一辆汽车的司机的 ID,但我无法弄清楚如何添加额外的计数步骤,以便我只返回至少拥有一辆汽车的司机的 ID 5!
SELECT DISTINCT d.id FROM drivers d
JOIN cars c ON c.driver_id = d.id
WHERE c.created_at >= NOW() - '3 weeks'::INTERVAL
我希望我能够做类似的事情(显然是伪代码)
SELECT DISTINCT d.id FROM drivers d
JOIN cars c ON c.driver_id = d.id
WHERE c.created_at >= NOW() - '3 weeks'::INTERVAL
AND d.id IN (SELECT <driver ids which have more than 5 cars created in the last 3 weeks>)
但事实证明并没有这么简单。
我正在 Rails 中工作,但最终编写了原始查询。有什么建议吗?
由于您使用的是 Postgres,因此您可以使用
GROUP BY
和 HAVING
,如下所示:
Driver
.joins(:cars)
.where(cars: {created_at: 3.weeks.ago..})
.group(:id)
.having(Arel.star.count.gt(4))
这将产生以下 SQL
SELECT
drivers.*
FROM
drivers
INNER JOIN cars ON cars.driver_id = drivers.id
WHERE
cars.created_at >= [3 weeks ago date]
GROUP BY
drivers.id
HAVING
COUNT(*) > 4
为了与您当前的实现保持一致,或者对于不支持仅按主键分组的数据库,我们可以使用
Driver.where(id:
Car.select(:driver_id)
.where(created_at: 3.weeks.ago..)
.group(:driver_id)
.having(Arel.star.count.gt(4))
)
这会产生
SELECT
drivers.*
FROM
drivers
WHERE
drivers.id IN (
SELECT
cars.driver_id
FROM
cars
WHERE
cars.created_at >= [3 weeks ago date]
GROUP BY
cars.driver_id
HAVING
COUNT(*) > 4
)