2013-04-03 34 views
7

Tôi có một vài yêu cầu SQL lớn liên quan đến tham gia trên các mô hình khác nhau trong ứng dụng đường ray của tôi. Một yêu cầu duy nhất có thể liên quan đến 6 đến 10 bảng.Làm cách nào để tham gia vào các truy vấn phụ bằng AREL?

Để chạy yêu cầu nhanh hơn, tôi muốn sử dụng truy vấn phụ trong các kết nối (theo cách đó tôi có thể lọc các bảng này trước khi tham gia và giảm các cột vào bảng tôi cần). Tôi đang cố gắng để đạt được điều này bằng cách sử dụng AREL.

Tôi nghĩ rằng tôi đã tìm ra giải pháp cho vấn đề của mình ở đó: How to do joins on subqueries in AREL within Rails, nhưng mọi thứ phải thay đổi vì tôi nhận được undefined method '[]' for Arel::SelectManager.

Có ai có ý tưởng làm thế nào để đạt được điều này (không sử dụng dây)?

+0

Bạn có thể hiển thị truy vấn bạn đang cố gắng không? – mguymon

+0

Vâng để đơn giản hóa nó đến mức độ cực đoan: SELECT A. * INNER JOIN (SELECT B.a_id TỪ B Ở đâu Bc> 4) B ON A.id = B.a_id –

+0

Bạn có nên mã Ruby bạn đang cố gắng cho truy vấn? – mguymon

Trả lời

8

Pierre, tôi đã nghĩ ra một giải pháp tốt hơn có thể là như sau (cảm hứng từ this gist):

a = A.arel_table 
b = B.arel_table 

subquery = b.project(b[:a_id].as('A_id')).where{c > 4} 
subquery = subquery.as('intm_table') 
query = A.join(subquery).on(subquery[:A_id].eq(a[:id])) 

Không có lý do đặc biệt để đặt tên bí danh như "intm_table", tôi chỉ nghĩ rằng nó sẽ ít khó hiểu hơn.

4

OK vì vậy vấn đề chính của tôi là bạn không thể tham gia Arel :: SelectManager ... NHƯNG bạn có thể tham gia một bí danh bảng. Vì vậy, để tạo ra các yêu cầu trong nhận xét của tôi trên:

a = A.arel_table 
b = B.arel_table 

subquery = B.select(:a_id).where{c > 4} 
query = A.join(subquery.as('B')).on(b[:a_id].eq(a[:id]) 
query.to_sql # SELECT A.* INNER JOIN (SELECT B.a_id FROM B WHERE B.c > 4) B ON A.id = B.a_id 
Các vấn đề liên quan