6

我有一张这样的桌子:

      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 似乎无法达到这个结果。这是我正在尝试的:

  • 模型有一个 'most_recent' 范围: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'),但感觉......错了。
4

2 回答 2

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 与该地址的最高日期不相关,则生成的“记录”将与实际存储在数据库中的不同。取决于可能重要或不重要的用例。对于 Mysql,只需更改max(id)为即可id解决该问题,但 IIRC Oracle 对此存在问题。

于 2013-03-21T13:51:14.510 回答
2

要显示唯一地址:

Searches.group(:address)

然后,您可以根据需要选择列:

Searches.group(:address).select('id,date')
于 2013-10-08T23:52:51.113 回答