【发布时间】:2016-11-01 16:47:50
【问题描述】:
我有一个运行 PostGres 的 Rails 4.2.5.x 项目。我有一个结构与此类似的表:
id, contact_id, date, domain, f1, f2, f3, etc
1, ABC, 01-01-16, abc.com, 1, 2, 3, ...
2, ABC, 01-01-15, abc.com, 1, 2, 3, ...
3, ABC, 01-01-14, abc.com, 1, 2, 3, ...
4, DEF, 01-01-15, abc.com, 1, 2, 3, ...
5, DEF, 01-01-14, abc.com, 1, 2, 3, ...
6, GHI, 01-11-16, abc.com, 1, 2, 3, ...
7, GHI, 01-01-16, abc.com, 1, 2, 3, ...
8, GHI, 01-01-15, abc.com, 1, 2, 3, ...
9, GHI, 01-01-14, abc.com, 1, 2, 3, ...
...
...
99, ZZZ, 01-01-16, xyz.com, 1, 2, 3, ...
我需要查询才能找到:
-
date的最新行 - 按域过滤
- 针对不同的
contact_id(分组依据?) - 行限制结果。在此示例中,我没有添加此复杂性,但需要将其考虑在内。如果有 50 个不同的联系人,我只对日期前 3 个感兴趣。
- ID 是主键。
- 其他列上有索引
-
fX列表示模型中需要的其他数据(例如联系电子邮件)。
在 MySQL 中,这将是一个简单的 SELECT * FROM table WHERE domain='abc.com' GROUP BY contact_id ORDER BY date DESC,然而,PostGres 抱怨说,在这种情况下:
ActiveRecord::StatementInvalid: PG::GroupingError: ERROR: column "table.id" must appear in the GROUP BY clause or be used in an aggregate function
我希望返回 3 行; 1、4 和 6。理想情况下,我想在单个查询中取回完整的行......但我接受我可能需要先进行一次查询以获取 ID,然后再进行一次查询以获取 find 项目我要。
这是我得到的最接近的:
ExampleContacts
.select(:contact_id, 'max(date) AS max_date')
.where(domain: 'abc.com')
.group(:contact_id)
.order('max_date desc')
.limit(3)
但是...这将返回 contact_id,而不是 id。我无法为该行添加 ID。
编辑:
基本上,我需要取回按非主键分组并按另一个字段排序的行的主键。
【问题讨论】:
-
DOH ;) 4.2.5.x ;) 我编辑
标签: sql ruby-on-rails ruby postgresql ruby-on-rails-4