2013-08-05 50 views
26

Tôi nhận được lỗi này trong chế độ sản xuất pg, nhưng hoạt động tốt trong chế độ phát triển sqlite3.PostgreSQL -ust xuất hiện trong mệnh đề GROUP BY hoặc được sử dụng trong hàm tổng hợp

ActiveRecord::StatementInvalid in ManagementController#index 

PG::Error: ERROR: column "estates.id" must appear in the GROUP BY clause or be used in an aggregate function 
LINE 1: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = ... 
      ^
: SELECT "estates".* FROM "estates" WHERE "estates"."Mgmt" = 'Mazzey' GROUP BY user_id 

@myestate = Estate.where(:Mgmt => current_user.Company).group(:user_id).all 
+2

với GROUP BY trong PostgreSQL, bạn không thể sử dụng cột trong danh sách lựa chọn nếu bạn không sử dụng trong nhóm theo. Không biết làm thế nào để dịch nó thành đường ray –

+0

Liên quan: http://stackoverflow.com/q/19601948/398670 –

+0

Có thể trùng lặp: http://stackoverflow.com/questions/19601948/must-appear-in-the- chức năng nhóm-by-khoản-hoặc-được-sử dụng-in-an-tổng hợp- –

Trả lời

3
@myestate1 = Estate.where(:Mgmt => current_user.Company) 
@myestate = @myestate1.select("DISTINCT(user_id)") 

đây là những gì tôi đã làm.

41

Nếu user_idPRIMARY KEY thì bạn cần phải nâng cấp PostgreSQL; các phiên bản mới hơn sẽ xử lý nhóm chính xác theo khóa chính.

Nếu user_id không phải là độc đáo cũng không khóa chính cho mối quan hệ 'bất động' trong câu hỏi, sau đó truy vấn này không có ý nghĩa nhiều, vì PostgreSQL không có cách nào để biết trị trả về cho mỗi cột của estates trong đó nhiều hàng chia sẻ cùng một user_id. Bạn phải sử dụng hàm tổng hợp thể hiện những gì bạn muốn, như min, max, avg, string_agg, array_agg, v.v ... hoặc thêm (các) cột quan tâm vào GROUP BY.

Hoặc bạn có thể thay đổi cụm từ truy vấn để sử dụng DISTINCT ONORDER BY nếu bạn thực sự muốn chọn một hàng tùy ý, mặc dù tôi thực sự nghi ngờ rằng có thể biểu thị thông qua ActiveRecord.

Một số cơ sở dữ liệu - bao gồm SQLite và MySQL - sẽ chỉ chọn một hàng tùy ý. Điều này được coi là không chính xác và không an toàn bởi nhóm PostgreSQL, vì vậy PostgreSQL tuân theo chuẩn SQL và coi các truy vấn đó là lỗi.

Nếu bạn có:

col1 col2 
fred 42 
bob  9 
fred 44 
fred 99 

và bạn làm:

SELECT col1, col2 FROM mytable GROUP BY col1; 

sau đó nó rõ ràng rằng bạn sẽ nhận được hàng:

bob  9 

nhưng những gì về kết quả cho fred ? Không có câu trả lời đúng để chọn, vì vậy cơ sở dữ liệu sẽ từ chối thực hiện các truy vấn không an toàn như vậy. Nếu bạn muốn lớn nhấtcol2 cho bất kỳ col1 bạn muốn sử dụng max tổng hợp:

SELECT col1, max(col2) AS max_col2 FROM mytable GROUP BY col1; 
+0

user_id là khóa chính trong bảng người dùng, nhưng trên trong bảng thuộc tính. –

+0

@HrishikeshSardar trong trường hợp này, truy vấn này không có ý nghĩa. Bất động sản nào trả về cho bất kỳ 'user_id' nào? Chọn một cách ngẫu nhiên? Nó sẽ không làm điều đó. Bạn phải sử dụng tổng hợp hoặc suy nghĩ lại những gì bạn đang làm. –

+0

Tôi đang cố gắng tìm ra là như thế nào nếu tôi có @estate với các giá trị như {1,1,2,3,4,5,6,6}, nhưng bây giờ tôi chỉ muốn {1,2,3,4,5 , 6} từ nó, tôi nên làm gì, trong ví dụ này tôi đã đưa ra mảng ua, nhưng tôi muốn cùng một thứ cho mảng băm –

14

Gần đây tôi đã chuyển từ MySQL sang PostgreSQL và gặp sự cố tương tự. Chỉ để tham khảo, phương pháp tốt nhất mà tôi đã tìm thấy là sử dụng DISTINCT ON như đề xuất trong này SO trả lời:

Elegant PostgreSQL Group by for Ruby on Rails/ActiveRecord

này sẽ cho phép bạn nhận được một bản ghi cho mỗi giá trị duy nhất trong cột của bạn lựa chọn phù hợp với các điều kiện truy vấn khác:

MyModel.where(:some_col => value).select("DISTINCT ON (unique_col) *") 

Tôi thích DISTINCT ON vì tôi vẫn có thể nhận được tất cả các giá trị cột khác trong hàng. Chỉ riêng DISTINCT sẽ chỉ trả về giá trị của cột cụ thể đó.

+1

'DISTINCT ON' rất hữu ích, nếu thích hợp. Nhưng trình kế hoạch truy vấn không thông minh với 'DISTINCT ON' như với' DISTINCT' hoặc 'GROUP BY' vì vậy nó đáng để tránh trừ khi bạn thực sự cần nó. Nó cũng không chuẩn. –

6

Sau khi tự nhận được lỗi, tôi nhận thấy Rails (Tôi đang sử dụng đường ray 4) tự động thêm 'thứ tự theo id' vào cuối truy vấn nhóm của bạn. Điều này thường dẫn đến lỗi ở trên. Vì vậy, hãy chắc chắn rằng bạn gắn thêm .order (: group_by_column) của bạn vào cuối truy vấn Rails của bạn. Do đó bạn sẽ có một cái gì đó như thế này:

@problems = Problem.select('problems.username, sum(problems.weight) as weight_sum').group('problems.username').order('problems.username') 
+5

Tôi đã có cùng một (default_scope đã ra lệnh cho mô hình của tôi). Vì vậy, những gì tôi đã làm là: 'Model.reorder (nil) .group_by (...)' theo cách này thứ tự được loại bỏ. – Mosselman

+0

nhận xét này ... phải là câu trả lời. – Dudo

Các vấn đề liên quan