2013-03-21 44 views
4

我有一個表是這樣的:選擇不重複的記錄,同時保持其他領域的完整

 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')
  • ​​返回全套(SELECT DISTINCT "searches".* FROM "searches" ORDER BY date DESC) - 顯然查詢是不會做我想做的,但也不是隻選擇一列。我需要所有列,但只有address在結果集中唯一的行。
  • 我可以做一些像Model.select('distinct(address), date, id'),但那種感覺......錯了。

回答

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對此存在問題。

+0

@ChrisCashwell:在sqlfiddle鏈接我張貼返回同樣的事情,在你的榜樣(每個地址的最近日期**),除了它總是返回每個地址的最高ID。你使用的是什麼RDBMS? – creinig 2013-03-21 16:05:22

2

要顯示的唯一地址:

Searches.group(:address) 

然後,如果你願意,你可以選擇列:

Searches.group(:address).select('id,date') 
+2

,並注意「group」將採用第一個「:address」匹配的id。 – Hugo 2013-10-09 00:00:40

+0

克里斯尼古拉,兩個命令都有效。使用「組」也可以看到接受的答案,並不明顯。我將這個替代方法作爲Ruby引用粘貼,因爲我已經成功地使用了它。而且它也完成了OP的目標。 – Hugo 2014-06-12 18:52:05