2014-02-23 38 views
8

我有一個簡單的UserDonations之間的關係,因爲用戶有很多捐款,捐款屬於一個用戶。 我想要做的是獲得最近捐款訂購的用戶列表。加入和訂單的不同記錄

這裏就是我想:

首先,我想uniq的用戶總數,這是按預期工作:

> User.joins(:donations).order('donations.created_at').uniq.count 
    (3.2ms) SELECT DISTINCT COUNT(DISTINCT "users"."id") FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" 
=> 384 

接下來,當我刪除count方法,我得到一個錯誤「ORDER BY表達式必須出現在選擇列表」:

> User.joins(:donations).order('donations.created_at').uniq 
    User Load (0.9ms) SELECT DISTINCT "users".* FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at 
PG::InvalidColumnReference: ERROR: for SELECT DISTINCT, ORDER BY expressions must appear in select list 
LINE 1: ...ON "donations"."user_id" = "users"."id" ORDER BY donations.... 

然後我試圖通過明確設置搜索固定Postgres的錯誤克SELECT子句乍一看似乎工作:

> User.select('DISTINCT "users".id, "users".*, "donations".created_at').joins(:donations).order('donations.created_at') 
    User Load (17.6ms) SELECT DISTINCT "users".id, "users".*, "donations".created_at FROM "users" INNER JOIN "donations" ON "donations"."user_id" = "users"."id" ORDER BY donations.created_at 

然而,回到不考慮DISTINCT語句,並記錄數返回692個記錄:

> _.size 
=> 692 

我如何獲得預期的結果數量(384),同時按捐贈的created_at時間戳排序?

+0

我想當你說'DISTINCT「users」.id,「users」。*,「donations」.created_at'服務器將其解釋爲:每個元素的一個結果在其所有字段中是唯一的 – juanpastas

回答

18

試試這個:

User.select('users.*,MAX(donations.created_at) as most_recent_donation'). 
    joins(:donations).order('most_recent_donation desc').group('users.id') 

我想一個用戶有很多捐款,這將選擇最近創建的捐贈,並會選擇不同的用戶通過他們的ID過濾。

雖然我沒有測試過。

+2

使用'group 'users.id')'我得到一個postgres錯誤「列」donations.created_at「必須出現在GROUP BY子句中或用於聚合函數」 –

+2

您的更新回答爲我工作,謝謝!我做的唯一改變是使用'order('most_recent_donation DESC')'因爲我正在使用[Kaminari分頁](https://github.com/amatsuda/kaminari),並且希望最近的捐助者首先使用。 –

+0

啊我明白了,很好。 – juanpastas