Sql được tạo bởi biểu thức không phải là một truy vấn hợp lệ, bạn đang nhóm theo user_id
và chọn rất nhiều trường khác dựa trên đó nhưng không cho DB biết cách nó sẽ tổng hợp các hồ sơ khác. Ví dụ:nếu dữ liệu của bạn trông giống như sau:
a | b
---|---
1 | 1
1 | 2
2 | 3
Bây giờ khi bạn yêu cầu db nhóm theo a
và cũng trả về b, nó không biết cách tổng hợp các giá trị 1,2
. Bạn cần biết nó có cần chọn min, max, trung bình, sum hay thứ gì khác không. Ngay khi tôi đang viết câu trả lời, có hai câu trả lời có thể giải thích tất cả điều này tốt hơn.
Tuy nhiên, trong trường hợp sử dụng của bạn, tôi nghĩ bạn không muốn một nhóm ở cấp db. Vì chỉ có 10 nghệ thuật, bạn có thể nhóm chúng trong ứng dụng của mình. Tuy nhiên, không sử dụng phương pháp này với hàng ngàn nghệ thuật:
arts = Art.all(:order => "created_at desc", :limit => 10)
grouped_arts = arts.group_by {|art| art.user_id}
# now you have a hash with following structure in grouped_arts
# {
# user_id1 => [art1, art4],
# user_id2 => [art3],
# user_id3 => [art5],
# ....
# }
CHỈNH SỬA: Chọn các mục mới nhất, nhưng chỉ chọn một tác phẩm cho mỗi người dùng
Chỉ để cung cấp cho bạn ý tưởng về sql (chưa thử nghiệm nó vì tôi chưa cài đặt RDBMS trên hệ thống của mình)
SELECT arts.* FROM arts
WHERE (arts.user_id, arts.created_at) IN
(SELECT user_id, MAX(created_at) FROM arts
GROUP BY user_id
ORDER BY MAX(created_at) DESC
LIMIT 10)
ORDER BY created_at DESC
LIMIT 10
Giải pháp này dựa trên giả định thực tế, rằng không có hai nghệ thuật nào cho cùng một người dùng có thể có cùng create_at cao nhất, nhưng nó có thể sai nếu bạn đang nhập hoặc lập trình tạo ra hàng loạt nghệ thuật. Nếu giả định không đúng, sql có thể nhận được nhiều vấn đề hơn.
CHỈNH SỬA: Cố gắng thay đổi truy vấn thành Arel:
Art.where("(arts.user_id, arts.created_at) IN
(SELECT user_id, MAX(created_at) FROM arts
GROUP BY user_id
ORDER BY MAX(created_at) DESC
LIMIT 10)").
order("created_at DESC").
page(params[:page]).
per(params[:per])