2015-02-04 21 views
7

Edit:Laravel: làm thế nào để sử dụng bảng có nguồn gốc/truy vấn phụ trong xây dựng truy vấn laravel

Mặc dù câu hỏi này ban đầu là cụ thể cho các truy vấn tôi mô tả bên dưới, câu trả lời tôi nhận được áp dụng cho hầu hết các câu hỏi có liên quan để sử dụng các bảng có nguồn gốc/truy vấn phụ trong Laravel

Câu hỏi gốc:

Gần đây tôi là một chút khó khăn trên người xây dựng truy vấn laravel. Nó có một số tính năng thực sự tốt đẹp nhưng tôi cảm thấy như nó chỉ không được xây dựng cho các hoạt động cơ sở dữ liệu phức tạp hơn.

Đây là truy vấn Tôi đang cố gắng để xây dựng:

select 

'IFNULL(counted.product_count, 0) AS product_count', 
'uncounted.value', 
'uncounted.attribute_id', 
'uncounted.attribute_option_id' 

    from ( 

     select 
     'counted.id', 
     'counted.attribute_id', 
     'counted.value', 
     'count(counted.attribute_id) AS product_count' 

     from `attribute_options` as `counted` 
     where `counted.product_id` in (?, ?, ?, ?, ?) 
     group by `counted.attribute_option_id` 

    ) as 'counted' 

right join 'attribute_options' as 'uncounted' 
     on 'counted.id' = 'uncounted.id' 

    group by 'attribute_option_id' 

Giải thích về truy vấn: Tôi đang xây dựng một tìm kiếm mặt cho danh mục sản phẩm của tôi trong laravel. Sản phẩm được thu hẹp dựa trên bộ lọc/thuộc tính mà người dùng cung cấp. Để có trải nghiệm người dùng tốt hơn, tôi muốn hiển thị số lượng sản phẩm còn lại cho mỗi bộ lọc, đó là những gì truy vấn trên thực hiện: đếm tất cả các sản phẩm cho một thuộc tính nhất định WHERE product_id nằm trong một mảng của id sản phẩm.

thử của tôi:

$productIds = [ 1, 2, 3, 4, 5 ]; 

    $subQuery = \DB::table('attribute_options')->selectRaw('counted.id, counted.attribute_id, counted.value, count(counted.attribute_id) AS product_count') 
        ->from('attribute_options AS counted') 
        ->whereIn('counted.product_id', $productIds) 
        ->groupBy('counted.attribute_option_id') 
        ->mergeBindings($subQuery); 

    $query = Model::selectRaw('IFNULL(counted.product_count, 0) AS product_count, uncounted.value, uncounted.attribute_id, uncounted.attribute_option_id') 
        ->from(\DB::raw(' (' . $subQuery->toSql() . ') AS counted ')) 
        ->rightJoin('attribute_options AS uncounted', 'counted.id', '=', 'uncounted.id') 
        ->groupBy('attribute_option_id') 
        ->get(); 

Xin hãy giúp tôi bởi vì tôi không muốn sử dụng một DB :: thô() hoặc DB :: select() tuyên bố. Điều đó sẽ không cảm thấy "Laravelish" hay "Eloquent".

+0

Vâng, bạn chắc chắn sẽ phải sử dụng ít nhất một DB: : raw() statement, để chọn ifnull. Đối với phần còn lại, tôi khuyên bạn nên đăng những gì bạn đã thử. Xin đừng mong đợi chúng tôi làm tất cả công việc cho bạn. –

+0

Kính gửi Joel, tôi chắc chắn không cố gắng để cho bạn làm tất cả công việc cho tôi! Tôi đã thử rất nhiều thứ trong tuần qua, nhưng tôi dường như không thể tìm được cách đúng để dịch SQL này để sử dụng trình tạo truy vấn. Tôi biết rằng IFNULL sẽ cần một câu lệnh selectRaw(). Tôi sẽ đăng những gì tôi đã thử. –

+0

Tốt hơn nhiều, có một upvote. :) Tôi xin lỗi tôi không thể giúp bạn với câu hỏi này, nhưng tôi hy vọng ai đó khác có thể. –

Trả lời

16

Lần thử đầu tiên của bạn có vẻ khá gần gũi. Hãy thử điều này:

tôi loại bỏ các tài liệu tham khảo không gian tên dài và đề nghị bạn thêm một tuyên bố use để làm cho mã của bạn dễ đọc hơn

$productIds = [ 1, 2, 3, 4, 5 ]; 

$subQuery = DB::table('attribute_options AS counted')->selectRaw('counted.id, counted.attribute_id, counted.value, count(counted.attribute_id) AS product_count') 
       ->whereIn('counted.product_id', $productIds) 
       ->groupBy('counted.attribute_option_id') 

$query = AttributeOption::selectRaw('IFNULL(counted.product_count, 0) AS product_count, uncounted.value, uncounted.attribute_id, uncounted.attribute_option_id') 
       ->from(\DB::raw(' (' . $subQuery->toSql() . ') AS counted ')) 
       ->mergeBindings($subQuery->getQuery()) 
       ->rightJoin('attribute_options AS uncounted', 'counted.id', '=', 'uncounted.id') 
       ->groupBy('attribute_option_id') 
       ->get(); 
+0

Ok! điều đó thực hiện mẹo, cảm ơn rất nhiều! Có thể thực hiện thủ thuật này trong nhiều lựa chọn lồng nhau/truy vấn phụ không? Tôi chỉ cần kết hợp các ràng buộc trước khi sử dụng get()? –

+0

Có điều đó sẽ hoạt động :) – lukasgeiter

+0

Tôi nhận thấy bạn đã đăng một [câu hỏi tương tự] (http://stackoverflow.com/questions/28283483/eloquent-how-to-use-the-query-builder-for-derived- bảng) Bây giờ điều này đã được giải quyết chưa? Nếu có, tôi khuyên bạn nên xóa câu hỏi cũ hơn. – lukasgeiter

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