2013-01-09 23 views
6

Điều này có vẻ khó hơn nó nên là:Postgres Rails Chọn biệt với thứ tự

Tôi muốn để có thể sắp xếp một bảng bằng cách đó là copy_count, sau đó chỉ chọn các sự kiện với một tiêu đề độc đáo, và hạn chế truy vấn để là người đầu tiên 99.

Event.order("copy_count DESC").select("DISTINCT ON (events.title) *").limit(99) 

này ném một lỗi:

ActiveRecord::StatementInvalid: PG::Error: ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions 

những đề nghị tôi cần phải thêm copy_count đến ON DISTINCT, nhưng điều này cũng sẽ chỉ kéo trở lại độc đáo hồ sơ copy_count whi ch có thể giống nhau!

Lưu ý: thứ tự bởi copy_count PHẢI xảy ra trước tiên.

Cảm ơn

+0

Vì vậy, bạn muốn 99 'events.title' có' copy_count' cao nhất mà không trùng lặp 'events.title'? –

+0

Đó là chính xác – jay

Trả lời

9

Đối với SQL tinh khiết nó sẽ trông giống như:

SELECT * 
FROM (SELECT DISTINCT ON (events.title) * 
     FROM events 
     ORDER BY events.title, events.copy_count DESC) top_titles 
ORDER BY events.copy_count DESC 
LIMIT 99 

Nhưng tôi không biết, làm thế nào để viết nó trong RoR.

+5

Sẽ là tuyệt vời để chuyển đổi nó thành cú pháp AR/Arel. – freemanoid

+1

có câu hỏi không chỉ định Rails - ai biết cách xác định điều này với giao diện AR Query? – Todd

4

Hãy thử điều này:

Event.order("copy_count DESC").limit(99).select(:title).uniq 
2

Nó có nghĩa là ORDER BY cần phải được "events.title, copy_count DESC". DISTINCT ON yêu cầu thứ đầu tiên bạn sắp xếp là danh sách các cột DISTINCT. Nếu bạn đang cố gắng để có được kết quả cao nhất cho mỗi tiêu đề, bạn phải nhóm chúng thành các tập hợp các hàng với cùng một tiêu đề đầu tiên trước khi bạn có thể sắp xếp theo copy_count. Nếu đó không phải là những gì bạn đang cố gắng làm, thì DISTINCT ON không phải là cấu trúc đúng.

1

Hãy thử điều này:

Event.select("DISTINCT ON (events.title) *").order("events.title, copy_count DESC").limit(99) 

Điều này xảy ra bởi vì khi bạn sử dụng câu lệnh DISTINCT ON, bạn phải sử dụng biểu hiện của nó (ví dụ events.title) trong ORDER BY biểu

SQL ERROR: SELECT DISTINCT ON expressions must match initial ORDER BY expressions 

Do đó, bạn chỉ cần thêm cột copy_count ngay sau events.title trong lệnh sao kê

0

Đây là những gì tôi đã thử:

Event.select('events.copy_count, RANDOM()').order('Random()').limit(10) 
Các vấn đề liên quan