我有一张这样的桌子:
table: searches
+------------------------------+
| id | address | date |
+------------------------------+
| 1 | 123 foo st | 03/01/13 |
| 2 | 123 foo st | 03/02/13 |
| 3 | 456 foo st | 03/02/13 |
| 4 | 567 foo st | 03/01/13 |
| 5 | 456 foo st | 03/01/13 |
| 6 | 567 foo st | 03/01/13 |
+------------------------------+
想要一个像这样的结果集:
+------------------------------+
| id | address | date |
+------------------------------+
| 2 | 123 foo st | 03/02/13 |
| 3 | 456 foo st | 03/02/13 |
| 4 | 567 foo st | 03/01/13 |
+------------------------------+
但ActiveRecord似乎无法实现这一结果。这是我正在尝试的:
scope :most_recent, order('date_searched DESC')
Model.most_recent.uniq
返回完整集(SELECT DISTINCT "searches".* FROM "searches" ORDER BY date DESC
) - 显然查询不会按我的意愿执行,但两者都不会只选择一列。我需要所有列,但只需要address
在结果集中唯一的行。Model.select('distinct(address), date, id')
之类的事情,但感觉......错了。答案 0 :(得分:3)
你可以做一个
select max(id), address, max(date) as latest
from searches
group by address
order by latest desc
根据sqlfiddle完全符合我的想法。
它与您的需求输出并不完全相同,它似乎并不关心返回哪个ID。但是,查询需要指定一些内容,这里由“max”聚合函数完成。
对于这种情况,我认为你对ActiveRecord的自动生成查询方法没有任何好运。因此,只需使用该SQL将您自己的查询方法添加到模型类中。它是完全标准的SQL,它也可以在任何其他RDBMS上运行。
编辑:查询的一大缺点是它不一定会返回实际记录。如果给定地址的最高ID与该地址的最高日期不相关,则生成的“记录”将与实际存储在DB中的记录不同。取决于可能重要或不重要的用例。对于Mysql,只需将max(id)
更改为id
即可解决该问题,但IIRC Oracle存在问题。
答案 1 :(得分:2)
显示唯一地址:
Searches.group(:address)
然后,您可以根据需要选择列:
Searches.group(:address).select('id,date')